第5回 WshShellオブジェクトの詳細(1):Windows管理者のためのWindows Script Host入門(2/4 ページ)
WshShellオブジェクトを利用し、スクリプトから外部プログラムを起動して、キー・ストロークを送信して制御する。
それでは、WshShellのメソッドやプロパティについて詳しく見ていくことにしよう。まずはRunメソッドとExecメソッドである。これら2つは、プログラムを起動するためのメソッドである。
RunメソッドとExecメソッド
Office製品やInternet Explorerなど、COMオブジェクトとして提供されているものは、WScriptオブジェクトのCreateObjectメソッドやGetObjectメソッドを利用してオブジェクトを生成し、生成したオブジェクトを直接操作した方がきめ細かい処理が行えるが、この方法はCOMオブジェクトが提供されないプログラムでは使えない。Windows標準のテキスト・エディタであるメモ帳や、比較的小規模のプログラムでは、COMオブジェクトとしてのアクセス方法が提供されていない場合が多い。これに対しRunメソッドやExecメソッドでは、実行形式のファイルさえあれば任意のプログラムを起動できる。汎用性の高いメソッドである。そして起動後は、AppActivate/SendKeysメソッド(後述)でキー・ストロークなどをプログラムに送信することで、実行したプログラムをスクリプトから制御することが可能となる。
RunメソッドとExecメソッドは、プログラムの実行方法に違いがある。Runメソッドは完全に別プロセスとしてプログラムを起動する。Runメソッドを使った場合に直接操作できるのは、起動の際に最小化・最大化などの表示方法を指定することと、プログラムの終了を待つ場合に終了コードを取得することのみである。一方Execメソッドは、コマンドライン・アプリケーションに対してよく用いられ、プログラムの標準入力/標準出力/標準エラー出力を利用できる。また、CScriptでスクリプトを実行した場合、Runメソッドでは現在とは別の新しいコマンド・プロンプトが作成されるが、Execメソッドでは新しいコマンド・プロンプトは表示されず、CScriptを実行したコマンド・プロンプトがそのまま使われる。RunメソッドとExecメソッドの違いをまとめると次のようになる。
Runメソッド | Execメソッド | ||
---|---|---|---|
終了コードの取得 | ○ | ○ | |
プロセスIDの取得 | × | ○ | |
WSH 5.6以前の環境での利用 | ○ | × | |
Windowsアプリケーション | |||
最大化・最小化状態で実行 | ○ | × | |
コマンドライン・アプリケーション | |||
標準入出力の利用 | × | ○ | |
ウィンドウ | 新しいコマンド・プロンプトを表示する | CScriptであれば表示しない | |
RunメソッドとExecメソッドの比較 |
詳細は後述するとして、最大の違いは、Execメソッドでは標準入出力(stdin/stdout)が利用できることだろう。Execメソッドを使えば、別のコマンドライン・ツールを起動して、その出力結果を受け取って処理することなどができる。一方のRunメソッドは、Windowsプログラムとして、最小化状態でこっそりスクリプトを実行する場合などに使う。ただし、ExecメソッドがサポートされるのはWSH 5.6以後である。古いWSH環境ではExecは使えないので注意すること。
Runメソッドの使い方
Runメソッドでプログラムを実行するには、実行したいプログラムのファイル名をパラメータとして指定する。実行プログラムに渡すべきオプションがあるなら、それらのオプションも含めて指定する。基本はファイル名をフルパスで指定することだが、実行パスが通っているフォルダにあるプログラムなら、ファイル名だけを指定しても実行できる。実行パスは環境変数PATHで管理されており、システムのプロパティで変更できる。
次の例では、3通りの方法でメモ帳を起動している。ただし、Windowsのシステム・フォルダが「C:\WINDOWS」であり(Windows 2000やWindows NTでは「C:\WINNT」)、スクリプトを実行しているフォルダに「test.txt」「test2.txt」があるものとする。
1:Set objShell = WScript.CreateObject("WScript.Shell")
2:objShell.Run "C:\WINDOWS\system32\notepad.exe"
3:objShell.Run "%SystemRoot%\notepad.exe test.txt"
4:objShell.Run "notepad test2.txt"
最初の例(2行目)では、Runメソッドのパラメータとして、実行したいプログラムをフルパスで指定している。第2の例(3行目)は環境変数%SystemRoot%を利用してパスを指定している(環境変数SystemRootは、通常は「C:\WINDOWS」が設定されている)。そして第3の例(4行目)ではパスと拡張子を省略して、「notepad」のみを指定している。このコードを実行すれば、メモ帳が3つ開くはずだ。そのうち2番目と3番目では、パラメータとしてファイル名を指定しているので、テキストファイルtest.txtとtest2.txtがそれぞれ開かれる。
Runメソッドの第2、第3パラメータ
前述の例はすべて1つのパラメータを指定しているが、Runメソッドには、第2、第3のパラメータを指定することもできる。このうち第2パラメータでは、ウィンドウの表示方法を0から10までの整数で指定する。例えば1なら最小化や最大化をせずに元のサイズで表示、2は最小化、3は最大化表示、などだ。詳細は次のとおり。
第2パラメータの値 | 意味 |
---|---|
0 | ウィンドウを非表示にし、別のウィンドウをアクティブにする |
1 | ウィンドウをアクティブにして表示する。ウィンドウが最小化または最大化されている場合は、元のサイズと位置に戻る |
2 | ウィンドウをアクティブにし、最小化ウィンドウとして表示する |
3 | ウィンドウをアクティブにし、最大化ウィンドウとして表示する |
4 | ウィンドウを最新のサイズと位置で表示する。アクティブ・ウィンドウは切り替わらない |
5 | ウィンドウをアクティブにし、現在のサイズと位置で表示する |
6 | 指定したウィンドウを最小化し、Zオーダー上で次に最上位となるウィンドウをアクティブにする |
7 | ウィンドウを最小化ウィンドウとして表示する。アクティブ・ウィンドウは切り替わらない |
8 | ウィンドウを現在の状態で表示する。アクティブ・ウィンドウは切り替わらない |
9 | ウィンドウをアクティブにして表示する。ウィンドウが最小化または最大化されている場合は、元のサイズと位置に戻る |
10 | アプリケーションを起動したプログラムの状態に基づいて表示状態を設定する |
Runメソッドの第2パラメータ |
このように、Runメソッドの第2パラメータを指定することで、実行するウィンドウの状態を制御できる。例えば、ユーザーに気付かれることなくプログラムを起動するような場合は、この第2パラメータに7を指定すれば、起動したプログラムは最小化表示され、現在のアクティブ・ウィンドウも切り替わらない(エンドユーザーに対する管理業務では、このような必要性に迫られる場面が少なからずある)。ただし、表示サイズが固定されているプログラムなどに対しては(固定サイズのダイアログで表示されるプログラムなど)、このパラメータは設定しても機能しないので注意が必要である。
Runメソッドの第3パラメータでは、起動したプログラムの終了を待つかどうかを指定する。先ほどのサンプルでは、3つのメモ帳がほぼ同時に起動されるが、次のように各Runメソッドの第3パラメータにTrueを指定すれば、起動したプログラムが終了するまでスクリプトの実行が停止するようになる。つまり、最初に起動されたメモ帳を終了すると2番目のメモ帳が起動され、これを終了すると第3のメモ帳が起動される…というふうに1つずつ順番に起動されるようになる。前出の例に第2、第3パラメータを追加してみよう。
1: Set objShell = WScript.CreateObject("WScript.Shell")
2: objShell.Run "C:\WINDOWS\system32\notepad.exe", 3, True
3: objShell.Run "%windir%\notepad.exe test.txt", 2, True
4: objShell.Run "notepad test2.txt",, True
このスクリプトを実行すると、まず最大化状態のメモ帳が表示され、そのメモ帳を終了すると最小化状態のメモ帳が表示され、それを終了すると最後に通常のメモ帳が表示される。最後のメモ帳を終了した時点でスクリプト全体も終了する。4行目のように、第2パラメータを省略して第3パラメータを指定する場合には、「,」を続けて記述する。
Runメソッドの第3引数にTrueを指定した場合には、起動したプログラムの終了コードをスクリプトで取得できる。例えば、ファイルの内容を比較するコマンドライン・ツールのFC.EXEは、比較したファイルが同一なら0を、違いがあれば1を返す(FCはFile Compareの略)。これを利用して、ファイルの比較結果を表示するスクリプトを作成してみよう。
1: Const MINIMIZE_WINDOW = 2
2: Set objShell = WScript.CreateObject("WScript.Shell")
3: fcresult = objShell.Run("fc.exe test.txt test2.txt", _
4: MINIMIZE_WINDOW, True)
5:
6: If fcresult = 0 Then
7: WScript.Echo "test.txtとtest2.txtは同じ内容のファイルです"
8: ElseIf fcresult = 1 Then
9: WScript.Echo "test.txtとtest2.txtは異なる内容のファイルです"
10: Else
11: WScript.Echo "FC が結果 " & fcresult & " を返しました"
12: End If
このスクリプトでは、第2パラメータの意味がコードからすぐ分かるように、2という数字をそのまま指定するのではなく、WSHのConstステートメントでMINIMIZE_WINDOWという定数に割り当てて使用している(1行目)。
第2パラメータに何も指定しないでFCコマンドを実行すると、FC用の新しいコマンド・プロンプトが最前面に表示されてしまうので、これを目立たなくするために最小化を指定している(3〜4行目)。このコードが先ほどの例と大きく異なる点もこの3〜4行目だ。メソッドの実行と代入文とを組み合わせることで、結果をfcresultに代入している。このような使い方をする場合には、メソッドのパラメータ全体を「( )」でくくる必要があるので注意が必要だ。終了コードを利用しない場合はメソッドがVBのSubプロシージャと同じように扱わるが、終了コードを利用する場合は関数のように扱われることに起因する(Subプロシージャには戻り値がない)。
スクリプトの後半(6〜12行目)では、FCコマンドから返された値によって処理を振り分け、結果に応じたメッセージを表示している。もちろん、FCによる結果を表示するだけなら、単純にFCを実行すればよいだけのことだが、このようにWSHから実行することで、FCコマンドの実行結果を別の処理で利用できるようになる。
Copyright© Digital Advantage Corp. All Rights Reserved.