【cdp】windows持久化运行cdp浏览器

【CDP】Windows 持久化运行 CDP 浏览器

背景

最近在 Windows 服务器上使用 Edge 浏览器的 CDP 调试模式,让 Agent 通过 Chrome DevTools Protocol 控制浏览器执行自动化操作。

Edge 启动命令大致如下:

bat 复制代码
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --remote-debugging-port=9222 --user-data-dir="E:\llq"

本地访问:

bat 复制代码
curl http://127.0.0.1:9222/json/version

可以正常返回 CDP 信息。

但是在远程 Windows 服务器上长期运行时,遇到了几个问题:

  1. 通过 MSTSC 手动启动 Edge,过一段时间后 Edge 进程可能退出。
  2. 127.0.0.1:9222 本地可访问,但远程 IP 的 9222 访问失败。
  3. netsh interface portproxy show all 规则还在,但 portproxy 实际没有监听。
  4. 重启 iphlpsvc 后恢复正常。
  5. 需要让 Edge CDP 能够长期稳定运行,异常退出后自动恢复。

最终采用的方案是:

text 复制代码
Edge CDP 启动脚本
+
Windows 任务计划程序
+
portproxy 端口转发
+
watchdog 定时检测和恢复

一、整体架构

最终访问链路如下:

text 复制代码
Agent
  |
  | 访问 http://192.168.113.193:9222
  v
Windows portproxy
  |
  | 转发到 127.0.0.1:9222
  v
Edge CDP

Edge 浏览器只监听本机:

text 复制代码
127.0.0.1:9222

通过 Windows portproxy 暴露给远程 Agent:

text 复制代码
192.168.113.193:9222 -> 127.0.0.1:9222

二、创建运行 CDP 的 BAT 启动脚本

创建目录:

bat 复制代码
mkdir C:\cdp-edge

创建启动脚本:

bat 复制代码
notepad C:\cdp-edge\start-edge-cdp.bat

写入以下内容:

bat 复制代码
@echo off
set EDGE=C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
set PROFILE=E:\llq

curl -s http://127.0.0.1:9222/json/version >nul 2>&1
if %errorlevel%==0 exit /b 0

start "" "%EDGE%" ^
  --remote-debugging-port=9222 ^
  --remote-allow-origins=* ^
  --user-data-dir="%PROFILE%" ^
  --no-first-run ^
  --no-default-browser-check ^
  --disable-popup-blocking

参数说明

参数 说明
--remote-debugging-port=9222 开启 CDP 调试端口
--remote-allow-origins=* 允许远程调试连接,避免部分 CDP 客户端连接失败
--user-data-dir=E:\llq 指定独立浏览器用户目录,避免和默认 Edge 用户目录冲突
--no-first-run 禁用首次启动引导
--no-default-browser-check 禁用默认浏览器检查
--disable-popup-blocking 禁用弹窗拦截,减少自动化场景异常

为什么要先 curl 检测?

脚本中有这一段:

bat 复制代码
curl -s http://127.0.0.1:9222/json/version >nul 2>&1
if %errorlevel%==0 exit /b 0

目的是避免重复启动多个 Edge CDP 实例。

如果 127.0.0.1:9222/json/version 已经正常返回,说明 Edge CDP 已经在运行,脚本直接退出。


三、配置 portproxy

如果 Agent 和 Edge 不在同一台机器上,需要让远程机器可以访问 Windows 服务器上的 CDP 端口。

假设 Windows 服务器 IP 是:

text 复制代码
192.168.113.193

添加 portproxy 规则:

bat 复制代码
netsh interface portproxy add v4tov4 listenaddress=192.168.113.193 listenport=9222 connectaddress=127.0.0.1 connectport=9222

查看规则:

bat 复制代码
netsh interface portproxy show all

正常应该看到:

text 复制代码
侦听 ipv4:                 连接到 ipv4:

地址            端口        地址            端口
--------------- ----------  --------------- ----------
192.168.113.193 9222        127.0.0.1       9222

注意:不要这样配置

不要配置成:

bat 复制代码
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=9222 connectaddress=127.0.0.1 connectport=9222

因为 0.0.0.0:9222 会包含 127.0.0.1:9222,很容易造成 portproxy 自己转发给自己,出现大量 ESTABLISHEDTIME_WAIT 连接。

错误链路类似:

text 复制代码
0.0.0.0:9222
  -> 127.0.0.1:9222
      -> 又命中 0.0.0.0:9222
          -> 继续转发

这种情况可能导致 9222 端口异常,甚至短时间内出现大量 TIME_WAIT。


四、配置防火墙策略

如果远程 Agent 需要访问 192.168.113.193:9222,需要放行 Windows 防火墙。

建议只允许 Agent 所在机器 IP 访问,不要暴露给所有地址。

假设 Agent IP 是:

text 复制代码
192.168.113.100

添加防火墙规则:

bat 复制代码
netsh advfirewall firewall add rule name="Allow Edge CDP 9222 From Agent" dir=in action=allow protocol=TCP localip=192.168.113.193 localport=9222 remoteip=192.168.113.100

如果是测试环境,也可以先放开当前内网段:

bat 复制代码
netsh advfirewall firewall add rule name="Allow Edge CDP 9222 From LAN" dir=in action=allow protocol=TCP localip=192.168.113.193 localport=9222 remoteip=192.168.113.0/24

不建议使用:

bat 复制代码
remoteip=any

CDP 端口权限很高,如果被非授权人员访问,可能会直接控制浏览器。


五、创建 watchdog 检测脚本

创建 watchdog 脚本:

bat 复制代码
notepad C:\cdp-edge\watchdog-edge-cdp.ps1

写入以下内容:

powershell 复制代码
$ErrorActionPreference = "SilentlyContinue"

$ListenIp = "192.168.113.193"
$ListenPort = 9222
$LocalCdpUrl = "http://127.0.0.1:9222/json/version"
$RemoteCdpUrl = "http://192.168.113.193:9222/json/version"

$EdgeExe = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
$Profile = "E:\llq"
$LogFile = "C:\cdp-edge\watchdog.log"

function Write-Log($msg) {
    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    "$time $msg" | Out-File -Append -Encoding utf8 $LogFile
}

function Test-Url($url) {
    try {
        $r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 5
        return ($r.StatusCode -eq 200)
    } catch {
        return $false
    }
}

function Ensure-IpHelper {
    $svc = Get-Service iphlpsvc
    if ($svc.Status -ne "Running") {
        Write-Log "iphlpsvc not running, starting..."
        Start-Service iphlpsvc
        Start-Sleep -Seconds 3
    }
}

function Ensure-PortProxy {
    $rulesText = (netsh interface portproxy show all) -join "`n"

    $expected = "$ListenIp\s+$ListenPort\s+127\.0\.0\.1\s+$ListenPort"

    if ($rulesText -notmatch $expected) {
        Write-Log "portproxy rule missing, recreating..."

        netsh interface portproxy delete v4tov4 listenaddress=$ListenIp listenport=$ListenPort | Out-Null
        netsh interface portproxy add v4tov4 listenaddress=$ListenIp listenport=$ListenPort connectaddress=127.0.0.1 connectport=$ListenPort | Out-Null

        Restart-Service iphlpsvc -Force
        Start-Sleep -Seconds 3
    }
}

function Start-EdgeCdp {
    Write-Log "starting Edge CDP..."

    Start-Process -FilePath $EdgeExe -ArgumentList @(
        "--remote-debugging-port=9222",
        "--remote-allow-origins=*",
        "--user-data-dir=`"$Profile`"",
        "--no-first-run",
        "--no-default-browser-check",
        "--disable-popup-blocking",
        "--disable-features=TranslateUI"
    )

    Start-Sleep -Seconds 5
}

Ensure-IpHelper
Ensure-PortProxy

$localOk = Test-Url $LocalCdpUrl
$remoteOk = Test-Url $RemoteCdpUrl

if ($localOk -and $remoteOk) {
    Write-Log "OK local and remote CDP healthy."
    exit 0
}

if (-not $localOk) {
    Write-Log "local CDP failed, restarting Edge..."

    Get-Process msedge | Stop-Process -Force
    Start-Sleep -Seconds 3

    Start-EdgeCdp
}

$localOk = Test-Url $LocalCdpUrl
$remoteOk = Test-Url $RemoteCdpUrl

if ($localOk -and -not $remoteOk) {
    Write-Log "local OK but remote failed, restarting iphlpsvc..."

    Restart-Service iphlpsvc -Force
    Start-Sleep -Seconds 3
}

$localOk = Test-Url $LocalCdpUrl
$remoteOk = Test-Url $RemoteCdpUrl

if ($localOk -and $remoteOk) {
    Write-Log "RECOVERED."
} else {
    Write-Log "FAILED after recovery. localOk=$localOk remoteOk=$remoteOk"
}

六、watchdog 脚本逻辑说明

这个脚本主要做几件事。

1. 检查 IP Helper 服务

portproxy 依赖 Windows 的 iphlpsvc 服务。

如果 iphlpsvc 没有运行,脚本会自动启动:

powershell 复制代码
Ensure-IpHelper

2. 检查 portproxy 规则

脚本会执行:

powershell 复制代码
netsh interface portproxy show all

然后判断是否存在:

text 复制代码
192.168.113.193 9222 127.0.0.1 9222

如果规则不存在,就自动重建:

powershell 复制代码
netsh interface portproxy add v4tov4 listenaddress=$ListenIp listenport=$ListenPort connectaddress=127.0.0.1 connectport=$ListenPort

3. 检查本地 CDP

本地检测地址:

text 复制代码
http://127.0.0.1:9222/json/version

如果本地不通,说明 Edge CDP 没有正常运行,脚本会重启 Edge。

4. 检查远程 CDP

远程检测地址:

text 复制代码
http://192.168.113.193:9222/json/version

如果本地通、远程不通,说明 Edge 本身正常,问题大概率在 portproxyiphlpsvc,脚本会重启 iphlpsvc


七、手动测试 watchdog

执行:

bat 复制代码
powershell.exe -ExecutionPolicy Bypass -File C:\cdp-edge\watchdog-edge-cdp.ps1

查看日志:

bat 复制代码
type C:\cdp-edge\watchdog.log

正常日志类似:

text 复制代码
2026-06-11 15:24:05 OK local and remote CDP healthy.

如果看到:

text 复制代码
portproxy rule missing, recreating...

说明脚本检测到 portproxy 规则不存在,并进行了重建。

如果每分钟都出现:

text 复制代码
portproxy rule missing, recreating...

则需要检查 Ensure-PortProxy 函数中的正则匹配逻辑,尤其注意 netsh interface portproxy show all 返回的是多行内容,需要先 join 成字符串:

powershell 复制代码
$rulesText = (netsh interface portproxy show all) -join "`n"

同时 127.0.0.1 里的点号需要转义:

powershell 复制代码
127\.0\.0\.1

八、创建登录启动任务

使用 Windows 任务计划程序,在用户登录时自动启动 Edge CDP。

执行:

bat 复制代码
schtasks /Create /TN "Start Edge CDP On Logon" /TR "C:\cdp-edge\start-edge-cdp.bat" /SC ONLOGON /RL HIGHEST /F

参数说明:

参数 说明
/TN 任务名称
/TR 要执行的命令或脚本
/SC ONLOGON 用户登录时执行
/RL HIGHEST 使用最高权限运行
/F 如果任务已存在则覆盖

手动执行一次:

bat 复制代码
schtasks /Run /TN "Start Edge CDP On Logon"

九、创建 watchdog 定时任务

每分钟执行一次 watchdog 检查:

bat 复制代码
schtasks /Create /TN "Watchdog Edge CDP" /TR "powershell.exe -ExecutionPolicy Bypass -File C:\cdp-edge\watchdog-edge-cdp.ps1" /SC MINUTE /MO 1 /RL HIGHEST /F

手动执行一次:

bat 复制代码
schtasks /Run /TN "Watchdog Edge CDP"

查看任务状态:

bat 复制代码
schtasks /Query /TN "Watchdog Edge CDP" /V /FO LIST

十、验证命令

1. 检查 Edge 本地 CDP

bat 复制代码
curl http://127.0.0.1:9222/json/version

正常会返回类似:

json 复制代码
{
   "Browser": "Microsoft Edge/...",
   "Protocol-Version": "1.3",
   "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/..."
}

2. 检查远程访问入口

bat 复制代码
curl http://192.168.113.193:9222/json/version

如果这个也正常,说明 portproxy 转发正常。

3. 检查端口监听

bat 复制代码
netstat -ano | findstr :9222

正常情况下应该看到类似:

text 复制代码
TCP    127.0.0.1:9222          0.0.0.0:0      LISTENING    Edge_PID
TCP    192.168.113.193:9222    0.0.0.0:0      LISTENING    svchost_PID

其中:

text 复制代码
127.0.0.1:9222

是 Edge CDP 本地监听。

text 复制代码
192.168.113.193:9222

是 portproxy 对外监听。

4. 检查 portproxy 规则

bat 复制代码
netsh interface portproxy show all

5. 检查 IP Helper 服务

bat 复制代码
sc query iphlpsvc

如果 portproxy 规则存在,但远程 IP 访问失败,可以尝试重启:

bat 复制代码
net stop iphlpsvc
net start iphlpsvc

十一、MSTSC 远程桌面注意事项

如果是在远程 Windows 服务器上通过 MSTSC 手动启动 Edge,需要注意:

  1. 关闭远程桌面窗口,通常只是断开连接,Edge 一般还会继续运行。
  2. 如果执行了注销,Edge 一定会退出。
  3. 如果服务器配置了远程桌面会话超时注销策略,断开一段时间后 Edge 也可能退出。
  4. Edge 是桌面进程,不建议简单用 Windows Service 方式运行。

所以更推荐:

text 复制代码
任务计划程序启动 Edge
+
watchdog 定时检测恢复

而不是单纯依赖 MSTSC 手工启动。


十二、常见问题排查

1. 本地 127.0.0.1:9222 正常,远程 IP:9222 不通

优先检查:

bat 复制代码
netstat -ano | findstr :9222

如果只看到:

text 复制代码
127.0.0.1:9222 LISTENING

没有:

text 复制代码
192.168.113.193:9222 LISTENING

说明 portproxy 没有实际监听。

处理方式:

bat 复制代码
net stop iphlpsvc
net start iphlpsvc

2. portproxy show all 有规则,但实际不监听

这是本次遇到的主要问题之一。

现象:

bat 复制代码
netsh interface portproxy show all

能看到规则。

但是:

bat 复制代码
netstat -ano | findstr :9222

看不到 192.168.113.193:9222 LISTENING

解决:

bat 复制代码
net stop iphlpsvc
net start iphlpsvc

3. 出现大量 TIME_WAIT

如果之前配置过:

text 复制代码
0.0.0.0:9222 -> 127.0.0.1:9222

可能导致 portproxy 自循环。

先删除错误规则:

bat 复制代码
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222

然后改成监听具体 IP:

bat 复制代码
netsh interface portproxy add v4tov4 listenaddress=192.168.113.193 listenport=9222 connectaddress=127.0.0.1 connectport=9222

4. Edge 自动退出

检查是否是远程桌面会话被注销:

bat 复制代码
query session

如果会话被注销,用户桌面进程会退出。

建议通过任务计划程序在登录时自动启动,并由 watchdog 定时恢复。


十三、最终部署检查清单

部署完成后,建议确认以下内容。

1. Edge CDP 本地正常

bat 复制代码
curl http://127.0.0.1:9222/json/version

2. 远程入口正常

bat 复制代码
curl http://192.168.113.193:9222/json/version

3. portproxy 规则正常

bat 复制代码
netsh interface portproxy show all

4. 端口监听正常

bat 复制代码
netstat -ano | findstr :9222

5. watchdog 日志正常

bat 复制代码
type C:\cdp-edge\watchdog.log

6. 任务计划存在

bat 复制代码
schtasks /Query /TN "Start Edge CDP On Logon" /V /FO LIST
schtasks /Query /TN "Watchdog Edge CDP" /V /FO LIST

总结

在 Windows 服务器上持久化运行 Edge CDP,不能只依赖 MSTSC 手工启动浏览器。

比较稳定的方式是:

text 复制代码
Edge 使用独立 user-data-dir 启动
portproxy 暴露远程访问入口
防火墙限制访问来源
任务计划程序登录时自动启动 Edge
watchdog 每分钟检测和恢复

最终实现效果:

  1. Edge 异常退出后自动拉起。
  2. iphlpsvc 异常后自动恢复。
  3. portproxy 规则丢失后自动重建。
  4. CDP 本地和远程访问都可以自动检测。
  5. Agent 可以长期稳定连接 Windows 上的 Edge CDP。
相关推荐
W优化大师1 小时前
Windows电脑频繁弹广告怎么彻底清除?从定位来源到卸载残留的完整方法
windows·电脑
拼搏的小浣熊2 小时前
【通用教程】Windows\+Linux\+银河麒麟系统 固定静态IP地址|解决打印机扫描IP变动、网络掉线问题
linux·网络·windows·麒麟·固定ip·麒麟系统·统信系统
w3296362712 小时前
使用 OpenCode 在 Windows 上加速安装 Playwright 的完整指南
windows·git
云烟成雨TD2 小时前
Agent Scope Java 2.x 系列【6】消息层
java·人工智能·agent
dabidai2 小时前
Docker PostgreSQL Windows 权限问题总结
windows·docker·postgresql
名不经传的养虾人2 小时前
从0到1:企业级AI项目迭代日记 Vol.46|三个检索源、缓存限流、深度整合——联网检索一日冲刺
数据库·人工智能·agent·ai编程·ai工作流·企业ai
l齐天2 小时前
Ubuntu 中编译 Go + PBC 程序为 Windows 11 可运行文件
windows·ubuntu·golang
caimouse2 小时前
Reactos 第 5 章 进程与线程 — 5.14 Windows线程间的相互作用
windows
晓py2 小时前
Windows 本地挂载阿里云 ECS,并使用 Claude 操作挂载路径学习文档
windows·学习·阿里云