首页 文章

SetWindowPos不适用于浏览器 - 没有MainWindowHandle?

提问于
浏览
1

我一直在尝试在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);

它似乎与Notepad一样好用,但是当它是浏览器时MainWindowHandle总是返回IntPtr.Zero,即使我刷新了Process .

任何建议?

1 回答

  • 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任务管理器或更好的Process Explorer,您会看到,当Chrome已经运行时,新的Chrome主窗口由已经运行的chrome.exe托管,并且 CreateProcess 启动的进程终止 .

    解:

    • 使用一些Window Enumeration API拍摄当前显示的Chrome主窗口的快照

    • 开始新的chrome.exe

    • 拍摄新快照 . 新窗口是第一个快照中不存在的窗口 .

相关问题