実現したいこと
Windowsフォームにて実行中のプロセスを取得し、取得したプロセスのファイルパスを参照して、指定したフォルダより下層にあるexeを全て終了させるプログラムを作りたいのですが、以下を試しても、目的の挙動が得られませんでした。現状の処理では取得したファイルパスに該当の文字列が含まれる場合はプロセスを終了という風に記載してますが、そもそもそれすら通りません。
こちらどなたか解決策をご教示いただけないでしょうか。
背景としましては
①フォームからexeを指定して実行
②実行したプロセスの終了
まではできたのですが、実行したexeの中には指定したexeを実行後に、さらに下層のフォルダのexeを開くという挙動をしているexe指定したexeを実行後に、さらに下層のフォルダのexeを開き、最初に開いたexeは既に終了しているという挙動をしているexeがありまして、その場合さらに下層のexeまでは終了できなかったため、全て終了させる手段として、実行中のプロセスのファイルパスを取得し、そのパスの中に該当の文字列が含まれている場合にプロセスを終了という形をとっています。
※おそらく現状だと最終的に残っているプロセスは最初に開いたプロセスの子や孫には該当しませんよね?
※もちろん、それでも条件によっては目的のexeが終了できない場合があることは分かってます。なので、そこも解消すべく、指定したフォルダより下層にあるexeを全て終了させるなどの事ができればなお良いです。ご教示お願いいたします。
発生している問題・分からないこと
実行中のプロセスの中に、指定した文字列がファイルパスに含まれる場合、プロセスを終了させたい。
該当のソースコード①で発生している事象は
例外がスローされました: 'System.ComponentModel.Win32Exception' (System.dll の中)
となり、そもそもプロセス終了の処理を通りません。
該当のソースコード②で発生している事象は
例外がスローされました: 'System.ComponentModel.Win32Exception' (System.dll の中)
System.ComponentModel.Win32Exception: '32 ビット プロセスは、64 ビット プロセスのモジュールにアクセスできません。'
となり、そもそもプロセス終了の処理を通りません。
該当のソースコード③で発生している事象は
②と同じ
該当のソースコード
C#
1//https://dobon.net/vb/dotnet/process/getprocesses.html 2//上記「Processクラスを使用した方法」を参照 3 4//上記を参照し、正常にすべてのプロセスを取得できているのを確認したので、トライの中をif文に書き換えました。 5 6//試したコード 7//ローカルコンピュータ上で実行されているすべてのプロセスを取得 8System.Diagnostics.Process[] ps = 9 System.Diagnostics.Process.GetProcesses(); 10 11foreach (System.Diagnostics.Process p in ps) 12{ 13 try 14 { 15 if (p.MainModule.FileName.Contains(指定文字列)) 16 { 17 p.Kill(); 18 } 19 } 20 catch (Exception ex) 21 { 22 //参照できない場合などは何もしない 23 } 24}
C#
1//https://dobon.net/vb/dotnet/process/getprocessesbywindowtitle.html 2//上記「Process.MainWindowTitleを使用する方法」を参照 3 4//上記を参照し、MainWindowTitleをMainModule.FileNamに変更しました。メソッドの型や不要なリスト等は削除してます。 5 6//試したコード 7 public void GetProcessesByFileName( 8 string searchstring) 9 { 10 //すべてのプロセスを列挙する 11 foreach (System.Diagnostics.Process p 12 in System.Diagnostics.Process.GetProcesses()) 13 { 14 try 15 { 16 //指定された文字列がMainModuleのFileNameに含まれているか調べる 17 if (0 <= p.MainModule.FileName.IndexOf(searchstring)) 18 { 19 //含まれていたら、プロセス終了 20 p.Kill(); 21 } 22 } 23 catch 24 { 25 26 } 27 28 } 29 }
C#
1//https://dobon.net/vb/dotnet/process/getprocessesbyfilename.html 2//上記「ProcessModule.FileNameを使用して探す」を参照 3 4//上記を参照し、以下の文を削除、メソッドの型や不要なリスト等は削除してます。 5//削除した箇所 ファイル名の部分を取得する fileName = System.IO.Path.GetFileName(fileName); 6 7//試したコード 8 public void GetProcessesByFileName(string searchFileName) 9 { 10 searchFileName = searchFileName.ToLower(); 11 12 //すべてのプロセスを列挙する 13 foreach (System.Diagnostics.Process p 14 in System.Diagnostics.Process.GetProcesses()) 15 { 16 string fileName; 17 try 18 { 19 //メインモジュールのパスを取得する 20 fileName = p.MainModule.FileName; 21 } 22 catch (System.ComponentModel.Win32Exception) 23 { 24 //MainModuleの取得に失敗 25 fileName = ""; 26 } 27 if (0 < fileName.Length) 28 { 29 30 //探しているファイル名が含まれていた場合、プロセス終了 31 if (searchFileName.Equals(fileName.ToLower())) 32 { 33 p.Kill(); 34 } 35 } 36 } 37 38 }
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
上記記載のエラー等で実行したい終了の処理が通りませんでした。
補足
visualstudio(最新):Windowsフォーム
言語:C#
文章も長くなってしまったため要領を得ない場合はすいません、
追加情報等必要あれば記載しますのでよろしくお願いします!