64bit環境で、Process.GetProcesses()を使用しウィンドウをもつプロセスのMainModule.FileNameを取得したい。
やたらと長いタイトルだが、やりたいことは、
- 起動中のプロセスから、ウィンドウをもっているプロセスを抽出したい。
- 抽出したプロセスの実行ファイル名を取得したい。
の2点である。
そして、前提条件として64bit環境で実行しているが、
32bitでビルドされたdllを使用しており、ビルドの構成はX86になっている。
素直にやると、こうなる
foreach (var p in Process.GetProcesses()) { // ウィンドウを持つプロセスのみ取得する if (p.MainWindowHandle != IntPtr.Zero) { Console.WriteLine(p.MainModule.FileName); } }
しかし、これを64bit環境で実行すると、
p.MainModuleにアクセスした時点で
32 ビット プロセスは、64 ビット プロセスのモジュールにアクセスできません。
とエラーが出る。
しょうがないので、ManagementClassから一度必要な情報を抽出して、
後からウィンドウ持ちのプロセスIDで引き当てる事にした。
using (var mc = new System.Management.ManagementClass("Win32_Process")) using (var moc = mc.GetInstances()) { var dic = new Dictionary<string, string>(); foreach (var mo in moc) { if (mo["ProcessId"] != null && mo["ExecutablePath"] != null && !dic.ContainsKey(mo["ProcessId"].ToString())) dic.Add(mo["ProcessId"].ToString(), mo["ExecutablePath"].ToString()); mo.Dispose(); } foreach (var p in Process.GetProcesses()) { // ウィンドウを持つプロセスのみ取得する if (p.MainWindowHandle != IntPtr.Zero) { if (dic.ContainsKey(p.Id.ToString())) Console.WriteLine(p.MainModule.FileName); } } }
どなたか、他に良い方法ご存じないですか?