プロセスの所有権を取得するウィンドウをどのように見つけますか?
それは誤解です、確かにあなたが立ち往生している理由です。ウィンドウはプロセスを所有していません。その逆です。そしてもっと微妙に、スレッドはウィンドウを所有しています。そして、プロセスはスレッドを所有します。
Process.GetProcesses()を使用すると、ウィンドウがまったくない多くのプロセスが列挙されます。マシン上で実行されるすべてのサービスと同様に、それらが数十あることは珍しいことではありません。タスクマネージャを使用して、[プロセス]タブでそれらを表示できます。必ず、すべてのユーザーが所有するプロセスを表示するオプションをクリックしてください。SysInternalsのProcessExplorerは、何が実行されているかを確認するための非常に優れたツールでもあります。
したがって、Process.MainWindowHandleがIntPtr.Zeroを返すことに驚かないでください。また、それは推測であることに注意してください。プロセスは、複数のトップレベルウィンドウを簡単に所有できます。それらのどれが「メイン」ウィンドウであるかは必ずしも明らかではありません。Processクラスは単純なルールを使用します。所有者がなく、表示されている最初のトップレベルウィンドウがメインウィンドウであると想定します。
プロセスのトップレベルウィンドウを確実に取得するには、最初にプロセス内のスレッドを列挙する必要があります。Process.Threadsで簡単に実行できます。次に、スレッドごとに、EnumThreadWindows()をピンボークすることにより、所有するウィンドウを繰り返し処理します。EnumWindows()とまったく同じアイデアですが、特定のスレッドに限定されており、ファイアホースの問題がなく、反復中に新しいウィンドウが作成されたために崩壊する可能性が低くなります。スレッドが所有するトップレベルウィンドウを取得します。各トップレベルウィンドウが所有する子ウィンドウを列挙するには、EnumChildWindows()が必要です。
いくつかの注目すべき悪いニュース:まともな結果を得るには、いくつかのフィルタリングが必要であることに注意してください。スレッドは非常に一般的に、まったく表示されないウィンドウを所有しています。スレッド間通信を処理するために一般的に使用され、特にCOMを使用するコードで一般的に使用されます。したがって、IsWindowVisible()もピンボークする必要があります。そして、これらのピンボークされた機能のエラーを常にチェックしてください。プログラムが管理者権限で実行されていない場合やUACが昇格されていない場合、失敗は一般的です。Spy ++ユーティリティから見えるもので、常に結果を再確認してください。