一种特殊情况下的问题:
System.Diagnostics.Process.Start(..)
启动一个进程 我需要获取进程的UI(或UI处理)。 假设我不能改变这个过程的行为,以使这个更容易(或更安全)。
我在网上看了一下,但我承认我没有找一个多小时。 看起来应该有点微不足道:-(
如果您不介意使用Windows API,则可以使用EnumWindowsProc
,然后检查每个使用GetWindowThreadProcessId
(看到它在您的进程中)出现的句柄,然后可能是IsWindowVisible
, GetWindowCaption
和GetWindowTextLength
来确定哪个hWnd
在你的过程中是你想要的。
虽然如果在这种方法之前你还没有使用过这些功能,那么这种方法将是一个很好的解决方法,所以希望有一个更简单的方法。
@ageektrapped在正确的轨道上,但是FindWindow
不会搜索子窗口。
为此,您将需要使用FindWindowEx
谢谢您的回答。 感谢你在这里,我想出了如何知道一个过程的主窗口是否在前面:
注意:当然这需要System.Diagnostic和System.Runtime.Interrop
public bool IsWindowActive(Int32 PID) { return IsWindowActive(Process.GetProcessById(PID)); } [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); public bool IsWindowActive(Process proc) { proc.Refresh(); return proc.MainWindowHandle.Equals(GetForegroundWindow()); }
您可能会发现,如果您调用.Refresh(),您将获得新的顶级窗口。
如果您知道该窗口的标题,则可以通过P / Invoke使用Win32调用FindWindow。
您可以在pinvoke.net上找到签名
从我所了解的MainWindowHandle
属性来看你正在启动的进程是无效的。 如果是这样的话,可以使用FindWindow
函数(从Win32 SDK),它返回你需要的窗口句柄。 所有你需要的是目标应用程序主窗口的类名称。 您可以使用Spy ++或Winspector获取它。 您还需要通过使用GetWindowThreadProcessId
检查窗口的进程ID来确保您拥有正确的窗口。
最后,我不得不说我不是Win32的专家,可能会有更好的解决方案。
使用Process.GetProcessById(proc.Id); proc是你的启动画面。 为我工作。
现在,你如何获得在System.Windows.Forms的主要窗口属性使它无焦点使用win32? 毕竟.net应该是一站式的解决方案 – 不是吗?
在代码的某个地方,“真正的”主窗口被创建。 您可以保存当时的窗口句柄,然后在启动画面关闭后,您可以将Application.MainWindow设置为真正的窗口。
MainWindowHandle属性在第一次访问之后被缓存,这就是为什么即使在句柄变为无效之后你也不会看到它改变的原因。 GregUzelac的信息是正确的。 调用Proces.Refresh将导致下一次调用Process.MainWindowHandle重新执行逻辑来查找新的主窗口句柄。 迈克尔的逻辑也适用,因为新的进程没有MainWindowHandle的缓存版本。