質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

1回答

6941閲覧

プロセスからウィンドウのタイトルを取得したい

yal

総合スコア41

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

1クリップ

投稿2021/10/25 13:27

前提・実現したいこと

https://dobon.net/vb/dotnet/process/getprocesses.html
このサイトを参考にプロセスから
プロセスid,プロセス名,タイトル名,パスを取得しようと考えていましたが,
それができません.ご教授お願い致します.

発生している問題・エラーメッセージ

元々,上記のサイトを参考にさせてもらいながら
GetProcessesメソッドを使ってプロセスから情報を取得しようと考えていました.
しかし,Win32Exceptonとエラーがでてしまうため,WMIのWin32_Processクラスを使用しようと考えました.
そして,大体の情報は取得できたのですが,肝心のタイトル名(GetProcessesメソッドでいうMainWindowTitle)が取得できません.

該当のソースコード

C#

1 private void getPro_Load(object sender, EventArgs e) 2 { 3 dataTable.Columns.Add("pid", typeof(int)); 4 dataTable.Columns.Add("プロセス名", typeof(string)); 5 dataTable.Columns.Add("タイトル名", typeof(string)); 6 dataTable.Columns.Add("パス", typeof(string)); 7 DataRow row; 8 9 System.Management.ManagementClass mc = new System.Management.ManagementClass("Win32_Process"); 10 System.Management.ManagementObjectCollection moc = mc.GetInstances(); 11 12 foreach(System.Management.ManagementObject mo in moc) 13 { 14 try 15 { 16 row = dataTable.NewRow(); 17 row["pid"] = mo["ProcessId"]; 18 row["プロセス名"] = mo["Name"]; 19 row["タイトル名"] = mo["status"]; 20 row["パス"] = mo["ExecutablePath"]; 21 dataTable.Rows.Add(row); 22 } 23 catch(Exception ex) 24 { 25 Console.WriteLine("エラーやよー"+ex.Message); 26 } 27 finally 28 { 29 mo.Dispose(); 30 } 31 } 32 moc.Dispose(); 33 mc.Dispose(); 34 35/* 36 //System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses(); 37 var processes = Process.GetProcesses(); 38 39 //foreach(System.Diagnostics.Process p in ps) 40 foreach(var process in processes) 41 { 42 try 43 { 44 row = dataTable.NewRow(); 45 row["pid"] = process.Id; 46 47 row["プロセス名"] = process.ProcessName; 48 // row["タイトル名"] = p.MainModule.ModuleName; 49 row["タイトル名"] = process.MainWindowTitle; 50 // row["パス"] = p.MainModule.FileName; 51 row["パス"] = process.MainModule.FileName; 52 dataTable.Rows.Add(row); 53 } 54 catch(Exception ex) 55 { 56 Console.WriteLine(ex.Message); 57 } 58 } 59*/ 60 dataGridView1.DataSource = dataTable; 61 }

試したこと

下記サイトを確認してMainWindowTitleに対応するようなものを探してみました.
https://docs.microsoft.com/ja-jp/windows/win32/cimwin32prov/win32-process

補足情報(FW/ツールのバージョンなど)

Windows 10 Home 20H2
VisualStudioVersion = 16.0.31624.102
C#
.NET framework 4.7.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cx20

2021/10/25 16:10

コメントアウトされた部分ですが、少し試してみたところ、 process.MainModule.FileName で Win32Exception が出ますが、 process.MainWindowTitle は取得できるようでした。
yal

2021/10/25 16:23

盲点でした.確かに今確認したらメインウィンドウタイトルとpidはGetProcessesメソッドでとれるのでWMIから拾ってきたプロセス名とパスをpidを使ってそれぞれ入れていけば行けそうですね. 参考になりました.今日は遅いので明日試してみます.ありがとうございます.
guest

回答1

0

自己解決

cx20さんの助言のおかげで解決しました.ありがとうございます.

最初にwmiのwin32_processを使ってpidなどタイトル名以外を取得しました.
そのあとgetprocessesメソッドからpidとタイトル名を取得して,辞書に入れて
datagridviewのrowとその辞書を全走査したらできました!

C#

1 private void getPro_Load(object sender, EventArgs e) 2 { 3 dataTable.Columns.Add("pid", typeof(int)); 4 dataTable.Columns.Add("プロセス名", typeof(string)); 5 dataTable.Columns.Add("タイトル名", typeof(string)); 6 dataTable.Columns.Add("パス", typeof(string)); 7 DataRow row; 8 9 Dictionary<int, string> title = new Dictionary<int, string>(); 10 11 System.Management.ManagementClass mc = new System.Management.ManagementClass("Win32_Process"); 12 System.Management.ManagementObjectCollection moc = mc.GetInstances(); 13 14 foreach(System.Management.ManagementObject mo in moc) 15 { 16 17 try 18 { 19 row = dataTable.NewRow(); 20 row["pid"] = mo["ProcessId"]; 21 row["プロセス名"] = mo["Name"]; 22 row["パス"] = mo["ExecutablePath"]; 23 dataTable.Rows.Add(row); 24 } 25 catch(Exception ex) 26 { 27 Console.WriteLine(ex.Message); 28 } 29 finally 30 { 31 mo.Dispose(); 32 } 33 } 34 moc.Dispose(); 35 mc.Dispose(); 36 dataGridView1.DataSource = dataTable; 37 38 39 var processes = Process.GetProcesses(); 40 41 foreach(var process in processes) 42 { 43 if (process.MainWindowTitle != "") 44 { 45 try 46 { 47 title.Add(process.Id, process.MainWindowTitle); 48 Console.WriteLine(process.Id + "," + process.MainWindowTitle); 49 } 50 catch (Exception ex) 51 { 52 Console.WriteLine(ex.Message); 53 } 54 } 55 } 56 57 foreach(KeyValuePair<int,string> x in title) 58 { 59 for(int i= 0; i < dataGridView1.Rows.Count; i++) 60 { 61 Console.WriteLine(dataGridView1[0, i].Value); 62 if(int.Parse(dataGridView1[0,i].Value.ToString()) == x.Key) 63 { 64 dataGridView1[2, i].Value = x.Value; 65 } 66 } 67 } 68 69 }

投稿2021/10/26 01:55

yal

総合スコア41

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問