0

我正在编写一个应该作为计划任务运行的 .exe,以检查我是否需要在特定监视器上打开运行 .Xbaps 的 IE 窗口。我有检查应该运行哪个 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

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

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

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

  • 在具有特定 URL X 的监视器 1 上以 Kiosk 模式启动 IE:
  • 在具有特定 URL Y 的监视器 2 上以 Kiosk 模式启动 IE:
4

1 回答 1

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);
于 2013-07-10T15:44:25.400 回答