如何在C#中获得Process的主窗口句柄?

Joh*_*ith 8 c# window process handle

目标是以编程方式启动Windows窗体,获取其句柄,并使用Win Api的SendMessage()函数将信息发送到其wndProc()函数.

我得到了SendMessage()部分,但现在的问题是在进程启动后获取表单的句柄.

我的第一个猜测是Process'MainWindowHandle属性会让我得到我正在寻找的句柄,但是在我启动进程之后MainWindowHandle保持等于0并且以下代码没有显示我刚开始的进程的句柄:

foreach (Process p in Process.GetProcesses())
{
Console.WriteLine(p.MainWindowHandle);
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我如何做到这一点,以及它是否可以实际完成?

Sim*_*Var 9

有时,Process会花一秒钟设置所有内容,但会立即返回该对象.

出于这个原因,你应该等一下,以便让进程真正启动它,然后它的MainWindowHandle将被适当地设置,准备好被消耗.

var proc = Process.Start("notepad");

Thread.Sleep(1000); // This will wait 1 second

var handle = proc.MainWindowHandle;
Run Code Online (Sandbox Code Playgroud)

另一种以更智能的方式实现这一目标的方法是:

var proc = Process.Start("notepad");

try
{
    while (proc.MainWindowHandle == IntPtr.Zero)
    {
        // Discard cached information about the process
        // because MainWindowHandle might be cached.
        proc.Refresh();

        Thread.Sleep(10);
    }

    var handle = proc.MainWindowHandle;
}
catch
{
    // The process has probably exited,
    // so accessing MainWindowHandle threw an exception
}
Run Code Online (Sandbox Code Playgroud)

这将导致进程启动,并等待MainWindowHandle不为空.

  • @JohnSmith你是对的,信息被缓存在对象中.调用`Refresh`方法会丢弃缓存的信息,因此下次访问`MainWindowHandle`属性时,它会根据需要从实际窗口中检索它.查看我的帖子的更新. (3认同)