2013年6月26日水曜日

Windowsで動作中の邪魔なプロセスを無理やり落とす

Windowsであるプログラムが常時走っていて、しかも手動で止められなかったりすると、
高負荷な処理をさせるときにそいつが邪魔でしょうがない時があります。
そんなときは[ctrl]+[shift]+[esc]でタスクマネージャを出して強制終了させるのですが、
もはやそれすらうっとうしいことがあります。

で、もうそいつを自動的に落としてしまおうとプログラムを書きかけました。
特定のファイル名(ここでは"sample.exe")を強制終了するには、
C+WinAPIなら以下のようなコードを実行すればいいようです。
    DWORD p[1024],num;
    unsigned int i,j;

    if (EnumProcesses(p,sizeof(p),&n)){
         j=num/sizeof(DWORD);
        for(i=0;i<num;i++){
            if(p[i]!=NULL){
                TCHAR name[MAX_PATH];
                HANDLE h;
                
                h=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,FALSE,p[i]);
                if(h!=NULL){
                    HMODULE m;
                    DWORD k;
                    if(EnumProcessModules(h,&m,sizeof(m),&k))
                        GetModuleBaseName(h,m,name,sizeof(name)/sizeof(TCHAR));
                }
                if(strcmp(name,"sample.exe"))
                    TerminateProcess(h,0);
                CloseHandle(h);
            }
        }
    }
    return 0;
}
ところでこのコードはコンパイルさえ試していないので動くかどうかわかりません。
というのも途中でもっと簡単な方法を見付けたからです。

Windowsにはtasklistとtaskkillのコマンドが用意されていることを知り、
これを使えば同等な機能をバッチファイルで実装できます。
cygwinを入れていれば以下の1行で可能です。
tasklist | grep sample.exe | awk '{print $2}' | xargs taskkill /F /PID
もし10秒に1回の頻度で"sample1.exe"と"sample2.exe"を強制終了したければ、例えば
#!/bin/bash
while :
do
 PID=`tasklist | grep sample1.exe | awk '{print $2}'`
 if [ -n $PID ]; then
  taskkill /F /PID $PID 2> /dev/null
 fi
 PID=`tasklist | grep sample2.exe | awk '{print $2}'`
 if [ -n $PID ]; then
  taskkill /F /PID $PID 2> /dev/null
 fi
 sleep 10
done
のようにシェルスクリプトを書いて実行すればいいだけです。
これでだいぶ快適になります。

0 件のコメント:

コメントを投稿