【问题标题】:Start Win32 process A which starts process B--get ID / HWND for B启动 Win32 进程 A 启动进程 B--获取 B 的 ID / HWND
【发布时间】:2011-06-01 14:46:53
【问题描述】:

好的,我在这个站点上花了一些时间来弄清楚如何使用来自 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,但我需要获取其中一个。

谢谢!

【问题讨论】:

    标签: c# .net winapi process win32-process


    【解决方案1】:

    一个简单的解决方案可能是,在尝试获取其 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;
                    }
                }
    

    【讨论】:

    • 感谢您的回答。奇怪的是,WaitForInputIdle 返回得非常快,并且 p (proc) 不为空。所以 p.MainWindowHandle 在没有 NullPointerException 的情况下工作。它只是返回 IntPtr.Zero。所以我目前返回null。我需要的是一种方法来监视 p 的进程调用并检查它的窗口句柄的新进程(假设 p 没有)。
    • 请注意,在查看您的代码时,我很确定在调用 Start() 之后 proc 永远不会为空。我不认为 start 方法会处理流程对象实例。相反,如果它失败和/或设置 HasExited 和 ExitCode 道具,它将引发异常。
    • 可以尝试使用 SendMessageTimeout 并查看窗口是否响应消息。如果它没有响应,你可以假设它已经死了。 Check this link for details on SendMessageTimeout 我认为任何解决方案都将涉及以某种方式使用更多 WIN API 调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多