「taskkill」コマンドでプログラムを起動
先ほどは特定のアプリケーションを自動起動するバッチファイルを作成しましたが、今度は起動したアプリケーションを閉じるバッチファイルを作成しましょう。ここで使用するのは様々な条件を元に実行中のプロセスを列挙する「tasklist」コマンドと、プログラムを終了する「taskkill」コマンド。前者は実行中のプログラムをプロセス名やウィンドウ名などで対象をしぼり込み、列挙することが可能です。後者は文字どおり指定したプログラムを終了させるためのコマンド。この両者を用いて起動したアプリケーションを終了させます(図06~07)。
まずはコマンドプロンプトから「tasklist」と実行してみましょう。するとプロセス名やプロセスIDなどが一覧表示されます。例えば複数のコマンドプロンプトを実行している場合、実行ファイルである「cmd.exe」も複数列挙されますが、これでは不要な情報が多いため、フィルター機能を使いましょう。「tasklist」では、イメージ名やCPU使用時間など様々な条件でしぼり込むことが可能です。例えばコマンドプロンプトだけをしぼり込む場合、「tasklist /fi "IMAGENAME eq cmd.exe"」と実行すれば、「cmd.exe」を使用したタスクのみ列挙されます(図08~09)。
「tasklist」コマンドで使用可能なフィルター
STATUS | eq, ne | RUNNING | NOT RESPONDING | UNKNOWN |
IMAGENAME | eq, ne | イメージ名 |
---|---|---|
PID | eq, ne, gt, lt, ge, le | PID値 |
SESSION | eq, ne, gt, lt, ge, le | セッション番号 |
SESSIONNAME | eq, ne | セッション名 |
CPUTIME | eq, ne, gt, lt, ge, le | CPU時間(hh:mm:ss, hh - 時間, mm - 分、ss - 秒) |
MEMUSAGE | eq, ne, gt, lt, ge, le | メモリ使用 (KB) |
USERNAME | eq, ne | (ドメイン)ユーザーの形式 |
SERVICES | eq, ne | サービス名 |
WINDOWTITLE | eq, ne | ウィンドウタイトル |
MODULES | eq, ne | DLL名 |
この機能を使えば、先のバッチファイルから起動されるアプリケーションのウィンドウタイトルは固定されますので、あとは同一のウィンドウタイトルを持つプロセスのIDを確認するだけとなります。このプロセスIDを導き出す方法として今回使用するのは、以前も取り上げた「for」コマンドです。「/F」オプションを用いることで、「tasklist」コマンド実行結果の各行を分割し、取り出しましょう。同オプションに「usebackq」を加えることで、「`(バッククォート)」で囲んだ文字列をコマンドとして実行します。続く「tokens」はどの部分を変数に代入してコマンド側に渡すかを指定するためのサブオプションです。言葉で説明してもわかりにくいでしょう。まずは図10~13をご覧ください(図10~12)。
図10 コマンドプロンプトから「tasklist /fi "WINDOWTITLE eq Google*"」と入力して[Enter]キーを押してください。これで「Google」というタイトルで始まるInternet Explorerのプロセス情報が表示されました |
図11 今度は「for /F "usebackq tokens=2" %a in (`tasklist /fi "WINDOWTITLE eq Google*"`) do @echo %a」と入力して[Enter]キーを押してください。先ほどとは異なりプロセスIDのみ表示されました |
図12 最後に「for /F "usebackq tokens=2" %a in (`tasklist /fi "WINDOWTITLE eq Google*" ^| findstr "[0-9]"`) do @echo %a」と入力して[Enter]キーを押してください。今度はプロセスIDの数値のみ表示されました |
まず図10の「tasklist」コマンドは単純に「Googleで始まるウィンドウタイトルを持つプロセス」を列挙させています。図11では、先の「tasklist」コマンドを分割するために「for」コマンドおよび各オプションを使用しました。ポイントは「tokens=2」の部分で、「2つ目のパートを取り出す」という意味になります。そして図12ではパイプを使用し、コマンドの実行結果を「findstr」コマンドに渡して文字列検索を行い、プロセスIDのみ抽出させました。このような流れで実行中のアプリケーションのプロセスIDを割り出し、「taskkill」コマンドで終了させることが可能になります。
リスト02
@echo off
setlocal
set KILL01=Google*
set KILL02=Microsoft Excel - memo.xlsx*
set KILL03=explorer.exe
:execute
for /F "usebackq tokens=2" %%a in (`tasklist /fi "WINDOWTITLE eq %KILL01%" ^| findstr "[0-9]"`) do @set RESULT=%%a
taskkill /pid %RESULT%
for /F "usebackq tokens=2" %%b in (`tasklist /fi "WINDOWTITLE eq %KILL02%" ^| findstr "[0-9]"`) do @set RESULT=%%b
taskkill /pid %RESULT%
for /F "usebackq tokens=1" %%c in (`tasklist /fi "IMAGENAME eq %KILL03%" ^| findstr "[0-9]"`) do @set RESULT=%%c
taskkill /pid %RESULT%
:end
endlocal
上記のロジックをバッチファイル化したのがリスト02です。あらかじめローカル環境変数で対象となるアプリケーションのウィンドウタイトルを設定していますので、イントラネットにアクセスした際に表示されるInternet Explorerのタイトルや、アプリケーション名およびファイル名といったご自身の環境に合わせて変更しましょう。ただし、作業フォルダーの自動終了を含める場合、煩雑な操作が必要となることをあらかじめご了承ください(図13~18)。
図13 [Win]+[R]キーを押し、ファイル名を指定して実行のテキストボックスに「notepad」と入力して<OK>ボタンをクリックします |
そもそもWindows 7のエクスプローラーは初期状態で同一のプロセスを用いてフォルダーを開く仕組みです。フォルダーオプションダイアログから設定を変更することで独立したプロセスを起動することも可能ですが、その後で開くフォルダーは同一のプロセスを使用するため、プロセスIDを用いて特定のフォルダーのみ閉じることはできません。また、エクスプローラー自身もウィンドウタイトルが付きませんので、「tasklist」コマンドのフィルター機能でしぼり込むことも不可能でした。
そのためWindows 7のデスクトップをつかさどるExplorer.exeにもプロセス終了命令が発せられるため、図17のようにWindows 7のシャットダウン操作がうながされるようになります。煩雑に感じる場合は5行目の「set KILL03=explorer.exe」、および12~13行目の「for /F "usebackq tokens=1" %%c in (tasklist /fi "IMAGENAME eq %KILL03%" ^| findstr "[0-9]"
) do @set RESULT=%%c」「taskkill /pid %RESULT%」を削除してフォルダーの自動終了処理を省いてお使いください。フォルダーの終了方法に関するより良い方法が見つかりましたら、本稿で改めて解説致します。
阿久津良和(Cactus)