3

さて、私はこのサイトで、C# からの Win32 呼び出しを使用して「子」プロセス (つまり、新しいプロセスがウィンドウの親を設定する) を開始する方法を理解するのに少し時間を費やしました。UACの境界を越えない限り、ちょっとうまくいきます。罰金。

現在、実際に作業を行う一時プログラム(プロセスB)をブートストラップするアンインストールプログラム(プロセスA)でこれを実行しようとしています。プロセス A は、B を作成した後に消えます。私のコードでは、SetParent に渡されるウィンドウ ハンドルを取得するためのプロセス ID が必要です。次のようになります。

Process p = new Process();
try
{
    p.EnableRaisingEvents = true;
    p.StartInfo.FileName = fileName;
    p.StartInfo.Arguments = arguments;
    if (p.Start())
    {
        p.WaitForInputIdle(10000);
        IntPtr pHwnd = p.MainWindowHandle;
        if (pHwnd == IntPtr.Zero)
        {
            return null;
        }
        IntPtr currentHwnd = Process.GetCurrentProcess().MainWindowHandle;
        if (SetParent(pHwnd, currentHwnd) == 0)
        {
            if (Marshal.GetLastWin32Error() == 5) // access denied
            {
                // Need to launch privileged process that launches process 
                // and sets parent on UAC enabled OS.
            }
            else
            {
                return null;
            }
        }
        // AND SO ON AND SO FORTH

p が消えない限り、うまく機能します。この場合、p は p' を開始した後にブームになります。いずれにしても、p にはウィンドウ ハンドルはありません。

では、p を監視して p' を開始するかどうかを確認し、p' の ID (または、より重要なウィンドウ ハンドル) を取得するにはどうすればよいでしょうか? ID から HWND を取得できますが、どちらかを取得する必要があります。

ありがとう!

4

1 に答える 1

0

簡単な解決策は、MainWindowHandle を取得する前に、p が null かどうかを確認することです。必要に応じて変更できるサンプル コードを次に示します。

           using (Process proc = new Process())
            {

                proc.StartInfo.FileName = filename;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.WorkingDirectory = ClientInstallPath;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

                proc.Start();

                if (proc != null)
                {
                    proc.WaitForExit();
                    returnCode = proc.ExitCode;
                }
            }
于 2011-06-01T16:18:00.467 に答える