You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现Edge窗口复用:在现有标签页跳转而非新建标签

问题描述

运行以下C#代码时,首次输入URL会打开Edge访问对应网站,但再次输入不同URL时,Edge会新建标签页打开。希望复用已打开的Edge窗口,在现有标签页直接跳转新URL,而非新建标签页。

原代码:

while (true)
{
    Console.WriteLine("Enter a URL");
    string strURL = Console.ReadLine();
    Process pWeb = new Process();
    pWeb.StartInfo.UseShellExecute = true;
    pWeb.StartInfo.FileName = "microsoft-edge:"+ strURL;
    pWeb.Start();
}
可行实现方案

方案一:通过Windows API操控Edge窗口

借助Windows API定位Edge主窗口与地址栏控件,模拟输入URL并触发跳转,无需额外配置。

实现步骤

  1. 引入必要命名空间:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
  1. 定义Windows API函数:
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam);

[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

private const uint WM_SETTEXT = 0x000C;
private const uint WM_KEYDOWN = 0x0100;
private const int VK_RETURN = 0x0D;
  1. 编写跳转逻辑:
static void NavigateInExistingEdge(string url)
{
    // 查找Edge主窗口(类名随Edge版本可能变化,可通过Spy++工具获取最新值)
    IntPtr edgeWindow = FindWindow("Chrome_WidgetWin_1", null);
    if (edgeWindow == IntPtr.Zero)
    {
        // 未找到Edge窗口时,新建窗口打开URL
        Process.Start(new ProcessStartInfo("microsoft-edge:" + url) { UseShellExecute = true });
        return;
    }

    // 定位Edge地址栏控件
    IntPtr addressBar = FindWindowEx(edgeWindow, IntPtr.Zero, "Chrome_OmniboxView", null);
    if (addressBar == IntPtr.Zero)
    {
        // 找不到地址栏时,fallback到新建窗口
        Process.Start(new ProcessStartInfo("microsoft-edge:" + url) { UseShellExecute = true });
        return;
    }

    // 激活窗口、设置地址栏URL、模拟回车跳转
    SetForegroundWindow(edgeWindow);
    SendMessage(addressBar, WM_SETTEXT, IntPtr.Zero, url);
    SendMessage(addressBar, WM_KEYDOWN, (IntPtr)VK_RETURN, IntPtr.Zero);
}
  1. 修改原循环调用该方法:
while (true)
{
    Console.WriteLine("Enter a URL");
    string strURL = Console.ReadLine();
    NavigateInExistingEdge(strURL);
}

方案二:使用Edge DevTools协议控制已打开实例

利用Edge支持的DevTools协议,通过WebSocket连接已打开的Edge实例,发送命令让现有标签页跳转。

实现步骤

  1. 先启动带远程调试端口的Edge实例(可手动启动或代码中检测启动):
start msedge.exe --remote-debugging-port=9222
  1. 编写C#控制逻辑:
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;

static async Task NavigateWithDevTools(string url)
{
    using var httpClient = new HttpClient();
    // 获取已打开页面的调试信息
    var response = await httpClient.GetAsync("http://localhost:9222/json");
    if (!response.IsSuccessStatusCode)
    {
        // 无调试端口的Edge实例,新建窗口打开URL
        Process.Start(new ProcessStartInfo("microsoft-edge:" + url) { UseShellExecute = true });
        return;
    }

    var pages = JsonSerializer.Deserialize<List<JsonElement>>(await response.Content.ReadAsStringAsync());
    if (pages == null || pages.Count == 0)
    {
        Process.Start(new ProcessStartInfo("microsoft-edge:" + url) { UseShellExecute = true });
        return;
    }

    // 获取第一个页面的WebSocket调试地址
    var webSocketDebuggerUrl = pages[0].GetProperty("webSocketDebuggerUrl").GetString();
    if (string.IsNullOrEmpty(webSocketDebuggerUrl))
    {
        Process.Start(new ProcessStartInfo("microsoft-edge:" + url) { UseShellExecute = true });
        return;
    }

    // 通过WebSocket发送跳转命令
    using var ws = new ClientWebSocket();
    await ws.ConnectAsync(new Uri(webSocketDebuggerUrl), CancellationToken.None);
    
    var command = new
    {
        id = 1,
        method = "Page.navigate",
        @params = new { url = url }
    };
    var jsonCommand = JsonSerializer.Serialize(command);
    var buffer = Encoding.UTF8.GetBytes(jsonCommand);
    await ws.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
    
    await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "操作完成", CancellationToken.None);
}
  1. 修改原循环调用该异步方法:
while (true)
{
    Console.WriteLine("Enter a URL");
    string strURL = Console.ReadLine();
    NavigateWithDevTools(strURL).Wait();
}

内容的提问来源于stack exchange,提问作者Pryach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:07:33