【问题标题】:How can I move a second opened browser window?如何移动第二个打开的浏览器窗口?
【发布时间】:2021-12-27 02:25:50
【问题描述】:

我正在尝试制作一个在每个多显示器上打开浏览器的程序。 当我用记事本做的时候,它起作用了。但是,当它是浏览器不工作并显示错误“System.InvalidOperationException:进程必须退出才能确定请求的信息”时。感谢您对这种情况的帮助。

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern int MoveWindow(IntPtr hwnd, int x, int y,
    int nWidth, int nHeight, int bRepaint);

        private void Form1_Load(object sender, EventArgs e)
        {

            foreach (Screen item in Screen.AllScreens)
            {
                //Open a web browser
                System.Diagnostics.Process process1 = System.Diagnostics.Process.Start("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe");
                //System.Diagnostics.Process process2 = System.Diagnostics.Process.Start("notepad.exe");
                process1.WaitForInputIdle();
                //process2.WaitForInputIdle();

                //Move the browser window
                MoveWindow(process1.MainWindowHandle, item.Bounds.X, item.Bounds.Y, item.Bounds.Width, item.Bounds.Height, 1);
                //MoveWindow(process2.MainWindowHandle, item.Bounds.X, item.Bounds.Y, item.Bounds.Width, item.Bounds.Height, 1);

            }
        }
    }
}

【问题讨论】:

  • 异常会抛出哪一行?
  • 第二次调试时这一行:MoveWindow(process1.MainWindowHandle, item.Bounds.X, item.Bounds.Y, item.Bounds.Width, item.Bounds.Height, 1);

标签: c# multiscreen


【解决方案1】:

好像msedge.exe使用了一个宿主进程来启动不同的标签页,所以我们不能使用创建的进程ID来处理它。

将创建的进程 ID 与任务管理器中的进程进行比较,即 进程38756 丢失。

另一个浏览edge相关进程的工具是edge的内置任务管理器。

我们也找不到进程38756

所以需要重新搜索目标edge进程。

这个 repo https://github.com/alex-tomin/Tomin.Tools.KioskMode 演示了如何将 chrome 窗口移动到不同的显示器并设置为全屏。

我尝试提取必要的并修改您的代码,如下所示,希望对您有所帮助:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestWinFormsApp
{
    // Get full definition of SetWindowPosFlags here:
    // https://www.pinvoke.net/default.aspx/Enums/SetWindowPosFlags.html
    [Flags]
    public enum SetWindowPosFlags : uint
    {
        SWP_NOREDRAW = 0x0008,
        SWP_NOZORDER = 0x0004
    }

    // Get full definition of ShowWindowCommands here:
    // https://www.pinvoke.net/default.aspx/Enums/ShowWindowCommand.html
    public enum ShowWindowCommands
    {
        Maximize = 3,
        Restore = 9,
    }

    public static class WinApi
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load_1(object sender, EventArgs e)
        {
            var ignoreHandles = new List<IntPtr>();
            foreach (Screen item in Screen.AllScreens)
            {
                this.StartEdgeProcess();

                var windowHandle = this.GetWindowHandle("msedge", ignoreHandles);
                ignoreHandles.Add(windowHandle);

                WinApi.ShowWindow(windowHandle, ShowWindowCommands.Restore);
                WinApi.SetWindowPos(windowHandle, IntPtr.Zero, item.Bounds.Left, item.Bounds.Top, 800, 600, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW);
                WinApi.ShowWindow(windowHandle, ShowWindowCommands.Maximize);
            }
        }

        private void StartEdgeProcess()
        {
            var process = new Process();
            process.StartInfo.FileName = "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe";
            process.StartInfo.Arguments = "about:blank" + " --new-window -inprivate ";
            process.Start();
            process.WaitForInputIdle();
        }

        private IntPtr GetWindowHandle(string processName, List<IntPtr> ignoreHandlers)
        {
            IntPtr? windowHandle = null;
            while (windowHandle == null)
            {
                windowHandle = Process.GetProcesses()
                    .FirstOrDefault(process => process.ProcessName == processName
                        && process.MainWindowHandle != IntPtr.Zero
                        && !string.IsNullOrWhiteSpace(process.MainWindowTitle)
                        && !ignoreHandlers.Contains(process.MainWindowHandle))
                    ?.MainWindowHandle;
            }

            return windowHandle.Value;
        }
    }
}

【讨论】:

  • 我已经搜索了 2 周没有结果!多亏了你的好意,我明白了。
  • 不客气。在搜索过程中我也学到了很多东西。如果有帮助,你能accept这个答案吗:)
  • 我做到了。再次感谢你XD
猜你喜欢
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 2019-12-10
  • 1970-01-01
相关资源
最近更新 更多