settwindowpos不能在浏览器上工作-没有MainWindowHandle
本文关键字:没有 MainWindowHandle 工作 不能 浏览器 settwindowpos | 更新日期: 2023-09-27 17:49:36
我一直在尝试用c#编写一个简单的程序,以启动不同的软件,并将其移动到特定的屏幕上,以便能够自动设置不同的窗口,在一台总共有12台显示器的机器上。
这些窗口大多是在Chrome或Internet Explorer中启动的。
我用来移动应用程序的代码如下:[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
this.process = Process.Start(this.startInfo);
process.WaitForInputIdle();
SetForegroundWindow(this.process.MainWindowHandle);
Console.WriteLine("Process ID: "+ this.process.Handle);
this.process.Refresh();
Console.WriteLine("Main window handle: " + this.process.MainWindowHandle);
Point screenlocation = Screen.AllScreens[MonitorNum].Bounds.Location;
SetWindowPos(this.process.MainWindowHandle, -1, screenlocation.X, screenlocation.Y, Screen.AllScreens[MonitorNum].Bounds.Width, Screen.AllScreens[MonitorNum].Bounds.Height, 1);
它似乎工作只是很好与记事本,但当它是一个浏览器mainwindowwhandle总是返回IntPtr。0,即使我刷新进程。
任何建议吗?
现代浏览器使用复杂的多进程架构。
当你启动一个新的chrome.exe进程时,如果一个chrome进程已经在运行,那么在两个进程之间会发生一些进程间通信,并启动一个新的子进程(旧的先前存在的进程的子进程)来承载新的选项卡渲染。您启动的进程然后立即退出,并且没有办法为现在已死亡的进程抓取主窗口。新的Chrome主窗口被创建是预先存在的进程。
你可以试试下面的c++源代码
#include <Windows.h>
#include <stdio.h>
int main( void ) {
STARTUPINFO SI;
memset( &SI, 0, sizeof SI );
SI.cb = sizeof SI;
PROCESS_INFORMATION PI;
BOOL bWin32Success =
CreateProcess( L"C:''Users''manuel''AppData''Local''Google''Chrome''Application''chrome.exe",
NULL, NULL, NULL, FALSE, 0, NULL,
L"C:''Users''manuel''AppData''Local''Google''Chrome''Application",
&SI, &PI );
if ( bWin32Success ) {
printf( "PID %u'n", PI.dwProcessId );
DWORD dwRet = WaitForInputIdle( PI.hProcess, 1000 );
switch ( dwRet ) {
case 0:
printf( "WaitForInputIdle succeedeed'n" );
break;
case WAIT_TIMEOUT:
printf( "WaitForInputIdle timed out'n" );
break;
case WAIT_FAILED:
printf( "WaitForInputIdle Error %u'n", GetLastError() );
break;
default:
printf( "WaitForInputIdle Unknown return value %d'n", dwRet );
}
CloseHandle( PI.hThread );
CloseHandle( PI.hProcess );
} else {
printf( "CreateProcess Error %u'n", GetLastError() );
}
return 0;
}
使用spy++和Windows任务管理器,或者更好的进程资源管理器,你会看到,当chrome已经运行时,新的chrome主窗口由已经运行的chrome.exe托管,并且CreateProcess
启动的进程被终止。
解决方案:
- 使用一些窗口枚举api对当前显示的Chrome主窗口进行快照
- 启动新的chrome.exe
- 创建一个新的快照。新窗口是第一个快照中不存在的窗口。