如何移动第二个打开的浏览器 window?

How can I move a second opened browser window?

我正在尝试制作一个在每个多显示器上打开浏览器的程序。 当我用记事本做的时候,它起作用了。但是,当浏览器无法正常工作并显示错误“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);

            }
        }
    }
}

似乎msedge.exe使用一个主机进程来启动不同的选项卡,所以我们不能使用创建的进程ID来处理它。

将创建的进程 ID 与任务管理器中的进程进行比较, 缺少进程 38756

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

我们也找不到进程 38756

所以重新搜索目标edge过程是必要的。

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

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

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;
        }
    }
}