C#: Windows 青魔法により別プロセスのコマンドラインを掠め取ってくる方法、または WMI の使用方法
残念な事に別プロセスの起動時に与えられたコマンドライン情報を System.Diagnostics.Process
の StartInfo
プロパティーの FileName
や Arguments
から取得はできない。それらはプロセスの起動を自身のプロセスから行う際に自身が設定した場合にのみ意味がある。別プロセスを相手にするのなら、そのアプローチは諦めよう。
ではどうするか?黒魔法は惜しいアイデアだ。 powershell
でも cmd
でも良いが、
wmic process where "processid=32096" get commandline /format:value
CommandLine="C:\Program Files\Epic Games\UE_4.19\Engine\Binaries\Win64\UE4Editor.exe" C:\Users\usagi\tmp\Experimental\Experimental.uproject -debug -game
などと取得できる。この実行例は UE4 プロジェクトを開発環境からデバッグ実行した状態で実行された Experimental プロジェクトのコマンドライン。プロセスIDはどうやって確認したのか?それは 1つ前の記事「UE4/C++: ジェネリック・プラットフォーム・罠ビリティー」 を眺めて欲しい。
wmic
を System.Diagnostics.Process
で StartInfo
の Arguments
に適当な引数を与えて標準出力から結果を読み出してパースすれば良い。そういうやり方は生きている世界にもよるが今回の記事のレベルとしては黒魔法という事にしておく。このような黒魔法的な方法も C++ アプリから WMI でさっくりと情報を取りたい場合には C++ネイティブコードで素直にDLLをリンクしてCOMを扱う よりもよほど現実的に便利だったりする事もある。
今回は C# なので WMI をあっさり使える。 "黒魔法" 的に実装するよりもせいぜい "青魔法" 的な実装で済む。 C# プロジェクトの References
に System.Management
を追加し、次のような実装を行えば先の wmic
と同様の事を "一応" C# だけで実装できる。
using System.Management; static private string GetProcessCommandline( Int32 process_id ) { using ( var s = new ManagementObjectSearcher() ) { s.Query.QueryString = "select * from win32_process"; using ( var c = s.Get() ) { var pid_string = process_id.ToString(); foreach ( var o in c ) if ( o[ "processid" ].ToString() == pid_string ) return o[ "commandline" ].ToString(); } } return null; }
C# のセンセイ級の諸姉諸兄におかれましてはにゃーんか納得できないお気持ちでしょうか。
「クエリーを文字列で書くのか👹」
はい、そういうわけで "青魔法" っぽいじゃないですか。あはは😅
「
foreach
使っていいのはISO/IEC 23270:2006 C# (2.0)
までだから👹」
ManagementObjectSearcher
系に Where
とか LINQ
対応を実装してくれていない Microsoft に言って下さい。
「その失敗
null
じゃなくて例外使えよ👹」、「WMI 原理主義者としてCommandLine
と書くべきと要求する👹」、「文字列じゃなくてInt32
に合わせて比較しろよ👹」…
自分で何か作る時には自分へ要求して下さい。本当に効率が良いか、必要な事なのかはさておき。
「にゃーん」
『にゃあああああああああああああああん♥』
と、いうわけで WMI "青魔法" 実装でした😃 C++ と違ってまだ必要ならちょろりと実装を書こうかという気がしますが、そもそも OS の API としてfjkfjk (゜∀。)
にゃーーーーん。
References
- wmic | Microsoft Docs
- ManagementObjectSearcher Class (System.Management) | Microsoft Docs
- ManagementObjectCollection Class (System.Management) | Microsoft Docs
- ManagementObject Class (System.Management) | Microsoft Docs
- ManagementObjectCollection.ManagementObjectEnumerator Class (System.Management) | Microsoft Docs
- WMI C++ Application Examples | Microsoft Docs
- ProcessStartInfo.FileName Property (System.Diagnostics) | Microsoft Docs