这是我的代码:
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();
}
}
问题是,那个游戏.MainWindowHandle总是IntPtr.Zero。我需要找到运行过程的IntPtr以确认游戏是由启动器启动的,所以我让游戏发送它的IntPtr并让发射器响应它是否正常。但为此,我必须专门了解运行过程的IntPtr。
提前致谢!
答案 0 :(得分:13)
主窗口是由当前具有焦点的进程(TopLevel表单)打开的窗口。您必须使用Refresh
方法将Process对象刷新为 获取当前主窗口句柄(如果已更改 )。
您只能为本地计算机上运行的进程获取MainWindowHandle
属性。 MainWindowHandle属性是唯一标识与进程关联的窗口的值。
只有当流程具有图形界面时,流程才会有与之关联的主窗口。如果关联的进程没有主窗口,则MainWindowHandle值为零。对于已隐藏的进程(即,任务栏中不可见的进程),该值也为零。对于在任务栏最右侧的通知区域中显示为图标的进程,情况可能就是如此。
如果您刚刚启动了一个进程并希望使用其主窗口句柄,请考虑使用WaitForInputIdle方法来允许进程完成启动,确保已创建主窗口句柄。否则,将抛出异常。
答案 1 :(得分:5)
解决方法是枚举所有顶级窗口并检查其进程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;
}
答案 2 :(得分:3)
while (!proc.HasExited)
{
proc.Refresh();
if (proc.MainWindowHandle.ToInt32() != 0)
{
return proc.MainWindowHandle;
}
}