3

好的,我在这个站点上花了一些时间来弄清楚如何使用来自 C# 的 Win32 调用来启动一个“子”进程(即,新进程为我设置窗口父进程)。只要它不跨越 UAC 边界,它就可以工作。美好的。

现在我正在尝试使用一个卸载程序(进程 A)来执行此操作,该程序引导一个实际执行工作的临时程序(进程 B)。进程 A 在创建 B 后消失。我的代码需要一个进程 ID,从中获取传递给 SetParent 的窗口句柄。看起来像这样:

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 是否为空。这是一些示例代码,您可以根据需要进行调整。

           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 回答