クリスマスとかアドベントカレンダーとか全然関係ない、Blue Prismの普通の記事です。
だって普通の平日ですよね?別に機嫌悪かったりしませんよ?
プロセスを終了させる、再度起動させる、で困った
プロセスを終了させるのには
標準VBOの「Utility - Environment」の中に「Kill Process」というのがあります。
しかしこのVBOをお使いになったかたで
「当該のアプリを終了させて、再度立ち上げようとしたときにうまく立ち上がらない」
というようなことに遭遇したかたもいらっしゃるかと思います。
うまくいかない理由(たぶん)
このVBOで使われているのは
Process.Kill メソッド
なんですけど、
これの「注意」っていうところに
すべての子孫がまだ終了していない場合でも、終了が完了したことを示します。
って書いてあって
つまりこれって、Killメソッドだと、孫以下の関連プロセスとかは終了しきれないでオバケになっちゃうってことですよね……?
それのせいで次に起動するときにそれが邪魔になってるってことでは……?
だったら確実に全部殺すにはどうしたらいいか
このコマンドを使えばいいらしい。Qiita探すとなんでも書いてあってすごいなあ。
taskkill コマンドで、プロセスを強制終了する
うしろにつけるオプションの説明は、こちらのMicrosoft 公式の説明を参照。
VBOでコマンドを実行するにはどうしたらいいかというと
DOSコマンドを実行し出力データを取得する
processオブジェクトの説明は
Process クラス(Microsoft公式の説明)
これらを踏まえて作ったもの
- 新しいVBOを作成して、「プロセス絶対殺す」と名前をつけたら、「Utility - Environment」VBOの「Kill Process」アクションをコピーしてきます。
Initializeで設定する名前空間は、「Utility - Environment」をそのまま真似して設定しました。DLLも真似して設定しとけばいいと思います。
コードステージの中を書き換えて、taskkillコマンドでプロセスを終了させるようにします。
入力引数は、元にした「Kill Process」と同じ「ProcessName」で、出力引数は無しです。
もし気になるなら、コードステージの前に入力引数がちゃんと入ってるかのチェックを入れとくといいかも。
VB
'Processオブジェクトを作成
Dim p As New System.Diagnostics.Process()
'ComSpec(cmd.exe)のパスを取得して、FileNameプロパティに指定
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec")
'taskkillコマンドをここで作ります
p.StartInfo.Arguments = "/c taskkill /F /T /FI ""username eq %USERNAME%"" /IM " & ProcessName
'初期化
p.StartInfo.UseShellExecute = false
p.StartInfo.CreateNoWindow = true
'起動
p.Start()
'プロセス終了まで待機してから終わる
p.WaitForExit()
p.Close()
バリエーションとして、プロセスIDを指定してそいつだけ狙ってkillするのも書きました。入力引数は「PID」です。データ型はNumber。c#
int iPID = (int)PID;
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(iPID);
if (p != null) {
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
p.StartInfo.Arguments = "/c taskkill /pid " + Convert.ToString(iPID);
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
p.Close();
}
終わりです
標準VBOの中身をずーっと読んでいくといろいろ勉強になるなあ、と最近思います。
あれ、これとこれのVBOは中身いっしょじゃん……?みたいなのも見つけたりしてちょっとおもしろいです。