代理关了,命令行为什么还在死磕 127.0.0.1:7892?三层代理排查 + 免管理员修复

一行报错引出的三层代理排查 + 一个免管理员修复方案。全程真实排查记录。

TL;DR 速查

症状 根因 修法
devecocli / npm / git 报 ECONNREFUSED 127.0.0.1:7892,代理软件明明已关 系统级环境变量残留:HTTP_PROXY / HTTPS_PROXY 指向已死的本地代理端口 删变量(或用户级空值覆盖),重开终端

一、问题现场

跑鸿蒙命令行工具登录:

C:\Users\34889>devecocli auth login
Starting login process...
Error: connect ECONNREFUSED 127.0.0.1:7892
Network connection failed (ECONNREFUSED).

关掉代理软件?没用。重启终端?没用。报错里的 7892 是以前代理软件监听的本地端口——软件没了,配置还活着,某个程序还在死脑筋地往这个黑洞里连。

二、先搞清楚:你的机器上有三层代理配置

排查前必须知道,Windows 上"代理"根本不是一个东西,是三个:

层 存储位置 谁在读
① 系统代理(浏览器层) 注册表 HKCU\...\Internet Settings 的 ProxyEnable / ProxyServer 浏览器、WinINet 程序、大部分 GUI 软件
② 环境变量层 HTTP_PROXY / HTTPS_PROXY(用户级或系统级) Node/CLI 程序(devecocli、npm、curl、axios 系全家桶)
③ git 专属层 git config --global http.proxy 只有 git

命令行工具几乎都读 ②,浏览器读 ①。关掉代理软件只是停止了监听,三层的配置一条都不会自动消失。

flowchart TD
    A["命令行报 ECONNREFUSED 127.0.0.1:7892"] --> B{"查环境变量"}
    B -->|当前会话有代理?| C["set #124; findstr /i proxy"]
    B --> D{"查注册表"}
    D --> E["用户级 HKCU\Environment:干净"]
    D --> F["系统级 HKLM\...\Environment"]
    F --> G["HTTP_PROXY = HTTPS_PROXY = http://127.0.0.1:7892<br/>← 元凶"]
    A --> H["git config --global"]
    H --> I["http.proxy = 7892<br/>← 另一处残留,顺带清理"]

三、定位根因

逐层查(PowerShell / Python winreg 都行):

# 用户级环境变量
[Environment]::GetEnvironmentVariable('HTTP_PROXY', 'User')
# 系统级环境变量 ← 元凶在这
[Environment]::GetEnvironmentVariable('HTTP_PROXY', 'Machine')
# 浏览器层系统代理(本次无关, 但要排除)
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select ProxyEnable, ProxyServer

结果:

用户级 HKCU\Environment : (无代理变量)
系统级 HKLM\...\Environment :
    HTTP_PROXY  = http://127.0.0.1:7892   ← 就是它
    HTTPS_PROXY = http://127.0.0.1:7892   ← 和它
git 全局: http.proxy = http://127.0.0.1:7892  ← 顺带发现另一份残留

image-20261003172621378

之前写的「一键关系统代理」bat 操作的是层 ①(ProxyEnable=0),对层 ② 完全无效——这就是"关了代理还是不行"的原因。

四、修复方案

方案 1:单窗口临时清(最快,不碰配置)

set HTTP_PROXY=
set HTTPS_PROXY=
devecocli auth login

set XXX=(等号后留空)只清当前窗口,关窗即恢复。赶时间就用这个。缺点:每开一个新窗口都要来一遍。

方案 2:用户级覆盖法 —— 免管理员,治本 ✅

关键冷知识:Windows 构建进程环境时,先装系统级变量,再用用户级同名变量覆盖。所以根本不用动 HKLM:

操作 实现 效果
关闭代理 在用户级写同名空值(REG_SZ "") 进程里 HTTP_PROXY 为空 → 程序直连;系统级配置原样保留
开启代理 删掉用户级空值覆盖 系统级 7892 自动恢复生效

全程只碰 HKCU\Environment,不需要管理员,无需 UAC。数据层实测:

1) 初始 HKCU: None None
2) 写空值后:  '' ''   ← 空值覆盖生效, 程序直连
3) 删除后:    None None ← 覆盖移除, 系统级 7892 恢复

两个实现细节:

  • 写空值用 reg add ... /d "",不依赖 setx VAR "" 的版本行为;
  • reg add/delete 不会通知系统刷新环境,补一个无害 hack:setx 写个临时变量(setx 自带 WM_SETTINGCHANGE 广播)再立刻 reg delete 删掉——广播发出去了,垃圾没留下。

最终脚本(可直接抄)

@echo off
setlocal
title 代理环境变量开关 (免管理员版)

::  原理: 系统级(HKLM)固定有 HTTP_PROXY/HTTPS_PROXY=127.0.0.1:7892
::   关闭 = 在用户级(HKCU)写同名空值覆盖 -> 程序直连 (无需管理员)
::   开启 = 删除用户级覆盖 -> 系统级 7892 重新生效 (无需管理员)
::  用法: 双击出菜单, 或命令行 "终端代理开关.bat off / on"

set "HKCUENV=HKCU\Environment"

if /i "%~1"=="off" goto dooff
if /i "%~1"=="on"  goto doon

:menu
cls
echo ==============================================
echo   代理环境变量开关 (用户级覆盖法, 不需要管理员)
echo   系统级固定值: http://127.0.0.1:7892
echo ==============================================
echo.
reg query "%HKCUENV%" /v HTTP_PROXY >nul 2>&1
if %errorlevel%==0 (
    echo   当前状态: [ 已关闭代理 - 程序直连 ]
) else (
    echo   当前状态: [ 已开启代理 - 127.0.0.1:7892 ]
)
echo.
echo   [1] 一键关闭代理 (直连, 跑 CLI 前用这个)
echo   [2] 一键开启代理 (恢复 7892)
echo   [0] 退出
echo.
set "choice="
set /p choice=请输入选项后回车: 
if "%choice%"=="1" goto dooff
if "%choice%"=="2" goto doon
exit /b

:dooff
reg add "%HKCUENV%" /v HTTP_PROXY  /t REG_SZ /d "" /f >nul
reg add "%HKCUENV%" /v HTTPS_PROXY /t REG_SZ /d "" /f >nul
call :broadcast
echo [OK] 已关闭代理 - 程序将直连.
goto tip

:doon
reg delete "%HKCUENV%" /v HTTP_PROXY  /f >nul 2>&1
reg delete "%HKCUENV%" /v HTTPS_PROXY /f >nul 2>&1
call :broadcast
echo [OK] 已开启代理 - 恢复 127.0.0.1:7892.
goto tip

:tip
echo.
echo 注意: 已经开着的终端读到的还是旧值, 请关掉终端重开.
echo.
pause
exit /b

:broadcast
:: 一次无害的 setx 触发 WM_SETTINGCHANGE 广播; 随后删掉临时变量
setx PROXY_SWITCH_DUMMY 1 >nul 2>&1
reg delete "%HKCUENV%" /v PROXY_SWITCH_DUMMY /f >nul 2>&1
goto :eof

image-20261003172957877
画面说明:黑底 cmd 窗口,顶部显示当前状态「已开启代理 - 127.0.0.1:7892」,下方三个选项 1/2/0。

五、附赠坑:关了变量还不够,要重开终端

环境变量在进程启动那一刻被读进内存。注册表改完,已经开着的 cmd/VS Code 终端读到的还是旧值。要么关掉重开,要么当前窗口手动 set HTTP_PROXY= 应急。

六、总结

  1. 代理软件关闭 ≠ 代理配置清除。环境变量、git config、IE 系统代理三层是独立的,命令行程序只认环境变量层。
  2. 命令行连不上网,先查 HTTP_PROXY/HTTPS_PROXY:set | findstr /i proxy 一秒出结果。
  3. 改系统级配置能不动就不动,用户级覆盖法免管理员、可逆、无 UAC,是更稳的工程选择。