获取第二个IE窗口以在不同的显示器上打开

时间:2013-07-09 20:21:31

标签: c# winapi xbap

我正在编写一个.exe,它应该作为计划任务运行,以检查我是否要求IE窗口在特定监视器上打开运行.Xbaps。我有代码检查应该运行的URL,如果不是我使用此代码启动它,然后将其移动到正确的监视器:

Process myProcess = Process.Start("iexplore.exe", "-new -k " + "http://server01:123/software.client.xbap");
myProcess.WaitForInputIdle();
Thread.Sleep(500);
MoveWindowToMonitor(myProcess.MainWindowHandle, 1);

窗口移动代码:

private static void MoveWindowToMonitor(IntPtr windowHandler, int monitor)
{
    RECT windowRec = new RECT();
    GetWindowRect(windowHandler, ref windowRec);

    int width = windowRec.Right - windowRec.Left;
    int height = windowRec.Top - windowRec.Bottom;

    if (width < 0)
        width = width * -1;

    if (height < 0)
        height = height * -1;


    SetWindowPos(windowHandler, (IntPtr)SpecialWindowHandles.HWND_TOP, Screen.AllScreens[monitor].WorkingArea.Left,
            Screen.AllScreens[monitor].WorkingArea.Top, width, height, SetWindowPosFlags.SWP_SHOWWINDOW);

}

运行快速测试版本会打开第一个IE窗口,Xbap启动,然后快速将其移动到我的其他监视器。当我第二次运行它而没有关闭第一个IE窗口时,我总是得到InvalidOperationException

  

“进程已退出,因此请求的信息不可用。”

我已经检查了我的任务管理器,因为这是我第一次运行任务时在详细信息下获得两个iexplore.exe项目,并且每次后续执行任务时只有一个额外的iexplorer.exe。每个xbap也会启动一个PresentationHost.exe。

任何人都知道我做错了什么或更好的方法吗? 我的最终目标是能够做到这一点:

  • 使用特定网址X:
  • 在监视器1上以Kiosk模式启动IE
  • 使用特定网址Y:
  • 在监视器2上以Kiosk模式启动IE

1 个答案:

答案 0 :(得分:0)

启动IE进程后,它会执行一些有趣的操作,并且您启动的进程偶尔可以在另一个接管窗口时立即结束。

我要做的是,使用下面的方法,EnumTheWindows将逐步浏览每个可见的窗口并查找Internet Explorer或我的baseURL。然后我将该窗口句柄传递给GetURL并获取IE窗口运行的特定URL。这允许我使用ConfirmProcessIsOnProperMonitor()和MoveWindowToMonitor()来获取适当监视器上的窗口。

重要的事情:

private static bool ConfirmProcessIsOnProperMonitor(IntPtr windowHandler, int monitor)
{
    //make sure you don't go to an incorrect monitor
    if (monitor >= Screen.AllScreens.Count()) monitor = Screen.AllScreens.Count() - 1;

    RECT windowRec = new RECT();
    GetWindowRect(windowHandler, ref windowRec);

    if (windowRec.Left != Screen.AllScreens[monitor].WorkingArea.Left || windowRec.Top != Screen.AllScreens[monitor].WorkingArea.Top)
        return false;
    else
        return true;
}

private static void MoveWindowToMonitor(IntPtr windowHandler, int monitor)
{
    //make sure you don't go to an incorrect monitor
    if (monitor >= Screen.AllScreens.Count()) monitor = Screen.AllScreens.Count() - 1;

    RECT windowRec = new RECT();
    GetWindowRect(windowHandler, ref windowRec);

    int width = windowRec.Right - windowRec.Left;
    int height = windowRec.Top - windowRec.Bottom;

    if (width < 0)
        width = width * -1;

    if (height < 0)
        height = height * -1;


    SetWindowPos(windowHandler, (IntPtr)SpecialWindowHandles.HWND_TOP, Screen.AllScreens[monitor].WorkingArea.Left,
            Screen.AllScreens[monitor].WorkingArea.Top, width, height, SetWindowPosFlags.SWP_SHOWWINDOW);

}

protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
{
    int size = GetWindowTextLength(hWnd);
    if (size++ > 0 && IsWindowVisible(hWnd))
    {
        StringBuilder sb = new StringBuilder(size);
        GetWindowText(hWnd, sb, size);
        string windowText = sb.ToString();

        if (windowText.ToLower().Contains(_baseURL) || windowText.ToLower().Contains("internet explorer"))
        {
            string url = GetURL(hWnd);
            _windowhandles.Add(hWnd, url);
        }
    }
    return true;
}

private static string GetURL(IntPtr intPtr)
{
    foreach (InternetExplorer ie in new ShellWindows())
    {
        if (ie.HWND == intPtr.ToInt32())
        {
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(ie.FullName);
            if ((fileNameWithoutExtension != null) && fileNameWithoutExtension.ToLower().Equals("iexplore"))
            {
                return ie.LocationURL;
            }
            else
            {
                return null;
            }
        }
    }

    return null;
}

难以阅读Windows API代码:

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int msg, IntPtr wParam, StringBuilder msgbody);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
protected static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")]
protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
protected static extern bool IsWindowVisible(IntPtr hWnd);