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) を再起動させてみます。
- 実行中の iexplore.exe のプロセスIDを検索・表示する
- プロセスを終了させる
- アプリケーションを起動する
実行中のプロセス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
とある名前のアプリケーションに対応するプロセスを終了させるには taskkill コマンドを利用します。taskkill は、オプション指定を行うことにより、アプリケーション名でプロセスを終了させることができます。
c:\test>taskkill /im iexplore.exe /f
成功: プロセス "iexplore.exe" (PID 5688) は強制終了されました。
成功: プロセス "iexplore.exe" (PID 7316) は強制終了されました。
成功: プロセス "iexplore.exe" (PID 4812) は強制終了されました。
/fは強制終了オプションです。
InternetExplorer は複数タブを開いている状態で終了しようとすると確認ダイアログが出てきますので、強制終了オプションを指定しない場合は OK ボタンを押さない限り終了されません。
そういった事情のあるアプリケーションの場合、強制終了オプションを指定することにより上記のように確認ダイアログによる問い合わせなしに停止可能です (ただし、強制終了で何かしら実害が生じるようであればこの強制終了オプションは利用しないで下さい)。
アプリケーションを起動するには start コマンドを利用します。start コマンドはアプリケーションを起動するコマンドになります。第一引数は実行ファイル名ではなくウィンドウのタイトルになるため、例えば下記のように空白文字列を与えます。
c:\test>start " " "C:\Program Files\Internet Explorer\iexplore.exe"
ではバッチファイルで実行させる方法を紹介します。
任意のアプリケーションを再起動させる手段(バッチファイル編)
では、上記でコマンドプロンプトで実施した内容をバッチファイルにしてみます。
今回やることはそう難しくないので簡単そうですが、バッチファイル(というかコマンドプロンプト)のクセを知らないとドツボにハマります。私はハマりました。
さて、アプリケーションの再起動の順序としては、
- 再起動させたいアプリケーションの名前と場所を変数に代入
- 実行中のプロセスから再起動させたいアプリケーション名のリストを取得
- リストがあればアプリケーションを終了させる
- 再起動させたいアプリケーションを起動する
早速ソースを見てみましょう。
@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文内のキャレット(^)です。% & | > < ( ) などの特殊文字はパイプや入出力として判断されますので、キャレットでエスケープしなければなりません。少し調べてみると、相当めんどくさい仕様となっているようなので、エスケープには気を付けた方がいいです。ドツボにハマります。詳しくは こちら に解析記事があります。
作成したバッチファイルをデスクトップやタスクバーに置いたり、ランチャーやマウスジェスチャーに登録すると、ダブルクリックでサクッとアプリケーションが再起動できて幸せになれます。
ディスカッション
コメント一覧
uzuki様
バッチファイルをコピーさせて頂きました。
(Windowsで任意のアプリケーションを簡単に再起動させる方法)
Dropboxの利用料が高額なのでGoogleDriveに変更したところ、PCがスリープする度にGoogleDriveSync.exeが動作を停止してしまうため、困っていました。
uzuki様のバッチファイルを見つけまして、少し自分用に改造してみたところバッチリです。
なかなかfor文をうまく使うのは難しいので、大変ありがたいです。ありがとうございました。
すごく分かりやすいです
Windows7をスリープ→復帰させると監視カメラアプリの画面が停止してしまう問題に悩んでいました
タスクトレイのアイコンから一度終了させ、監視カメラを再度起動すれば済むだけの事なのですが、上司から「面倒くさいから何とかしろ」とクレームが来たので簡単に出来る方法を探していました
あとはスリープ復帰イベントと同時に再起動が実行されれば言うことはありませんが、自分にはちょっと難しい世界のようですね
ありがとうございました!
とても助かりました。
少し重たいアプリケーションを使用しているのですが、毎回起動する度に「いつも起動しておこう」と思っていました。
そこで、一度起動した後、「閉じる」を選択するようにしたのですが、何気なく「終了」させてしまうこともありイライラしていました。
タスクに登録して、一定時間ごとにバッチを動かすようにしました。ありがとうございました!
情報ありがとうございます ググって辿り着きました
コマンドやらプログラムやらなにもわからないのですが 丁寧な説明でしたので コピペ中級ぐらいならできる私でも成功することが出来ました
win10で有線接続PS3コンとジョイスティック入力接続ソフトを利用時
・スリープ復帰後にPS3コンがデバイスマネージャーから消える
・PS3コン裏のリセットボタンを押してPCに再認識させるも接続ソフト側は再認識してくれない
・接続ソフトを再起動することによりPS3コンを認識させる→使える
…という面倒臭い作業の半分くらいは解消された感じです
バッチファイル自体はタスクスケジューラーで復帰後対応はできそうですが、先にPS3コンを再認識させなくてはならない当方の環境下では、スリープに負けないPS3コンの解決方法を探していきたいかと
ありがとうございました