【问题标题】:C# Process.MainWindowHandle always returns IntPtr ZeroC# Process.MainWindowHandle 总是返回 IntPtr 零
【发布时间】:2013-04-17 14:30:15
【问题描述】:

这是我的代码:

            using (Process game = Process.Start(new ProcessStartInfo() { 
        FileName="DatabaseCheck.exe",
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        UseShellExecute = false }))
        {
            lblLoad.Text = "Loading";
            int Switch = 0;

            while (game.MainWindowHandle == IntPtr.Zero)
            {
                Switch++;
                if (Switch % 1000 == 0)
                {
                    lblLoad.Text += ".";
                    if (lblLoad.Text.Contains("...."))
                        lblLoad.Text = "Loading.";

                    lblLoad.Update();
                    game.Refresh();
                }
            }

问题是,game.MainWindowHandle 总是 IntPtr.Zero。我需要找到 run 进程的 IntPtr 来确认游戏是由启动器启动的,所以我让游戏发送它的 IntPtr 并让启动器响应是否正常。但为此,我必须具体了解运行进程的 IntPtr。

提前致谢!

【问题讨论】:

    标签: c# process intptr window-handles


    【解决方案1】:

    一种解决方法是枚举所有顶级窗口并检查它们的进程 ID,直到找到匹配项...

    
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr parentWindow, IntPtr previousChildWindow, string windowClass, string windowTitle);
    
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowThreadProcessId(IntPtr window, out int process);
    
        private IntPtr[] GetProcessWindows(int process) {
            IntPtr[] apRet = (new IntPtr[256]);
            int iCount = 0;
            IntPtr pLast = IntPtr.Zero;
            do {
                pLast = FindWindowEx(IntPtr.Zero, pLast, null, null);
                int iProcess_;
                GetWindowThreadProcessId(pLast, out iProcess_);
                if(iProcess_ == process) apRet[iCount++] = pLast;
            } while(pLast != IntPtr.Zero);
            System.Array.Resize(ref apRet, iCount);
            return apRet;
        }
    

    【讨论】:

    • 只是想提一下,为了查找其他进程的窗口,这种解决方法在 Unity 上效果很好(同时使用 Refresh + MainWindowHandle 总是给我零指针)
    【解决方案2】:
    while (!proc.HasExited)
    {
        proc.Refresh();
        if (proc.MainWindowHandle.ToInt32() != 0)
        {
            return proc.MainWindowHandle;
        }
    }
    

    【讨论】:

    • 您好,您的帖子已被标记为“低质量”,可能是因为它仅包含代码。您可以通过解释这究竟是如何以及为什么回答问题来大大改进您的答案?
    • 对于阅读这篇旧文章的任何人......我记得在某个地方读到,由于 x64 与 x86,使用类似的东西不是一个好主意。改用IntPtr.Zero != proc.MainWindowHandle 可能会更好。
    【解决方案3】:

    主窗口是当前具有焦点的进程打开的窗口(TopLevel 窗体)。您必须使用 Refresh 方法刷新 Process 对象以获取当前主窗口句柄(如果它已更改)

    您只能为在本地计算机上运行的进程获取MainWindowHandle 属性。 MainWindowHandle 属性是唯一标识与进程关联的窗口的值。

    只有当进程具有图形界面时,该进程才具有与之关联的主窗口。如果关联进程没有主窗口,则 MainWindowHandle 值为零。对于已隐藏的进程,即在任务栏中不可见的进程,该值也为零。这可能是在任务栏最右侧的通知区域中显示为图标的进程。

    如果您刚刚启动了一个进程并想使用它的主窗口句柄,请考虑使用 WaitForInputIdle 方法让进程完成启动,确保已创建主窗口句柄。否则会抛出异常。

    【讨论】:

    • 我在家的时候会试试。谢谢
    • 请注意,在 4.5 上,这不再是必需的(轶事 - 我的代码在 4.5 上工作,当我降到 3.5 时失败,直到我添加 .Refresh()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多