Windowsで任意のアプリケーションを簡単に再起動させる方法

uzukiDOS,windows,バッチファイル

初めまして。セールスフォースグループの uzuki です。

他のメンバーは Linux や PHP のことについてよく書いていますので、趣向を変えて Windows のことについて書きたいと思います。

Windows には Linux と同じく CUI で操作を行うことが可能な「コマンドプロンプト」という機能があります。MS-DOS 世代の方ならご存じかと思いますが、要は Linux のシェルとほぼ同じような機能です。詳しくは コマンド プロンプト: よく寄せられる質問 に記載がありますので、ご一読頂ければと思います。

また、Linux のシェルスクリプトと同じく、あらかじめファイルに書いておいた命令を行わせることが可能です。このファイルのことを「バッチファイル」と呼びますが、今回はバッチファイルを作成して、任意のアプリケーションを再起動させる方法について書きたいと思います。

バッチファイル とは

先程記載した通り、バッチファイルとは言わば Windows 版のシェルスクリプトのようなものです。作成方法は単純で、拡張子を「.bat」にするだけでバッチファイルとなります。
Cドライブ配下に「test」フォルダを作成し、その中に「hello.bat」というファイルを作成します。hello.bat の上で右クリック⇒編集をクリックし、以下の内容を記載します。

echo hello!
pause

echo はその名の通り、引数を出力するコマンドです。pause を末尾に入れておかないと、コマンドプロンプトのウィンドウがすぐに閉じてしまうため入れています。

このファイルを実行すると、以下の内容で出力されるかと思います。

C:\test>echo hello!
hello!

C:\test>pause
続行するには何かキーを押してください . . .

実行したコマンドが表示されており、なんだか不格好なので、実行したコマンドを非表示にしたいと思います。先程の hello.bat に 1 行加えるだけで実行したコマンドは非表示になります。

@echo off
echo hello!
pause

実行結果は以下の通りとなります。

hello!
続行するには何かキーを押してください . . .

以上がおおまかなバッチファイルの作成方法となります。

任意のアプリケーションを再起動させる手段(コマンドプロンプト編)

バッチファイルの応用例として、任意のアプリケーションをワンタッチで (強制的に) 再起動する方法を紹介しようと思いますが、まずその前段として、コマンドプロンプトで任意のアプリケーションを再起動する方法からご説明します。

例として iexplore.exe (InternetExplorer) を再起動させてみます。

  1. 実行中の iexplore.exe のプロセスIDを検索・表示する
  2. 実行中のプロセスID (PID) を表示させる tasklist コマンドを利用します。
    tasklist は、オプション指定で任意のアプリケーション名 (tasklist コマンドにおける「イメージ名」) に対応するプロセスのみを表示させることが可能です。

    c:\test>tasklist /fi "IMAGENAME eq iexplore.exe"
    
    イメージ名                     PID セッション名     セッション# メモリ使用量
    ========================= ======== ================ =========== ============
    iexplore.exe                  5688 Console                    1     26,584 K
    iexplore.exe                  7316 Console                    1     55,076 K
    iexplore.exe                  4812 Console                    1     44,200 K
  3. プロセスを終了させる
  4. とある名前のアプリケーションに対応するプロセスを終了させるには taskkill コマンドを利用します。taskkill は、オプション指定を行うことにより、アプリケーション名でプロセスを終了させることができます。

    c:\test>taskkill /im iexplore.exe /f
    成功: プロセス "iexplore.exe" (PID 5688) は強制終了されました。
    成功: プロセス "iexplore.exe" (PID 7316) は強制終了されました。
    成功: プロセス "iexplore.exe" (PID 4812) は強制終了されました。

    /fは強制終了オプションです。

    InternetExplorer は複数タブを開いている状態で終了しようとすると確認ダイアログが出てきますので、強制終了オプションを指定しない場合は OK ボタンを押さない限り終了されません。
    そういった事情のあるアプリケーションの場合、強制終了オプションを指定することにより上記のように確認ダイアログによる問い合わせなしに停止可能です (ただし、強制終了で何かしら実害が生じるようであればこの強制終了オプションは利用しないで下さい)。

  5. アプリケーションを起動する
  6. アプリケーションを起動するには start コマンドを利用します。start コマンドはアプリケーションを起動するコマンドになります。第一引数は実行ファイル名ではなくウィンドウのタイトルになるため、例えば下記のように空白文字列を与えます。

    c:\test>start " " "C:\Program Files\Internet Explorer\iexplore.exe"

ではバッチファイルで実行させる方法を紹介します。

任意のアプリケーションを再起動させる手段(バッチファイル編)

では、上記でコマンドプロンプトで実施した内容をバッチファイルにしてみます。

今回やることはそう難しくないので簡単そうですが、バッチファイル(というかコマンドプロンプト)のクセを知らないとドツボにハマります。私はハマりました。

さて、アプリケーションの再起動の順序としては、

  1. 再起動させたいアプリケーションの名前と場所を変数に代入
  2. 実行中のプロセスから再起動させたいアプリケーション名のリストを取得
  3. リストがあればアプリケーションを終了させる
  4. 再起動させたいアプリケーションを起動する

早速ソースを見てみましょう。

@echo off
rem 再起動させたいアプリケーションの実行ファイル名とそのパスを変数に代入
set APP_NAME=iexplore.exe
set APP_FOLDER=C:\Program Files\Internet Explorer\

rem 対象のアプリケーションが起動しているかどうかを、tasklist コマンドと 
rem for 文の組み合わせで判定。tasklist コマンドの結果のうち、
rem /f オプションにより先頭の文字列 (空白またはタブ等の区切り文字まで) 
rem のみを取得し、%%i に代入
for /f %%i in ('tasklist /fi "IMAGENAME eq %APP_NAME%" 2^>^&1') do (
    rem 先頭の文字列がアプリケーション名と等しければ一つ以上のプロセスが
    rem 実行中であり、アプリケーションが起動していると見なせるため、
    rem taskkill で停止処理を実施
    rem (一致がなければアプリケーションは停止していると見なし何もしない)。
    if /i %%i==%APP_NAME% (
        rem taskkill でアプリケーション名を対象にして複数のプロセスを一度に停止
        taskkill /im %APP_NAME% /f
        rem アプリケーション停止後、breakなんて気の利いた機能はないので 
        rem goto でループから抜ける。
        goto ENDLOOP;
    )
)
:ENDLOOP

rem 再起動させたいアプリケーションを起動
start " " "%APP_FOLDER%%APP_NAME%"

わざわざ tasklist でリストを取得・for で処理する必要があるのか? taskill 後に start すればいいじゃないか! とのご指摘もあるかと思います。こんな周りくどいことをしている理由は、アプリケーションが起動している時のみ taskkill で停止する動きとしたかったからです。

例えば、存在しないアプリケーションを taskkill しようとすると以下のような「エラー(Error)」が生じます。

c:\test>taskkill /im iexplore.ex /f
エラー: プロセス "iexplore.ex" が見つかりませんでした。

一方で tasklist でアプリケーション名を指定し、検索を行った場合、そのアプリケーションが動作していない状況では「情報(Information)」として結果が返ってきます。

c:\test>tasklist /fi "IMAGENAME eq iexplore.ex"
情報: 指定された条件に一致するタスクは実行されていません。

分かっていてエラーを生ずるようなコマンドを実行するよりは、必要な時だけ taskkill を実施するような動きとなった方が筋が良いかなと思い、tasklist でアプリケーションのプロセスの有無を確認した上で taskkill を実施しています。その方法としてあまり for 文は他の言語では利用しないかもしれませんが、コマンドプロンプトで利用できるコマンドと制御構造においては比較的妥当な方法かなと思っています (もちろん他にもっとスマートな方法もあると思いますが)。

なお、バッチファイルのソースを書く上で注意しなければならないのは、for文内のキャレット(^)です。% & | > < ( ) などの特殊文字はパイプや入出力として判断されますので、キャレットでエスケープしなければなりません。少し調べてみると、相当めんどくさい仕様となっているようなので、エスケープには気を付けた方がいいです。ドツボにハマります。詳しくは こちら に解析記事があります。

作成したバッチファイルをデスクトップやタスクバーに置いたり、ランチャーやマウスジェスチャーに登録すると、ダブルクリックでサクッとアプリケーションが再起動できて幸せになれます。

uzukiDOS,windows,バッチファイル

Posted by uzuki