Gloxina
格洛西纳
Gloxina

通过脚本快速配置 Windows 代理

通过脚本快速配置 Windows 代理

太长不看版

下载即可使用,包含 AutoProxy.exe 和 Config.yaml,在 Config.yaml 中进行配置后双击运行 exe 文件即可开启/关闭代理,可以通过下面的 .py 源码自行构建 exe 程序。
下载地址:Gloxina Cloud

注意事项

下面的脚本/软件全部涉及到 Windows 注册表的修改,如果你需要对其进行修改,请确保你具有相关的背景知识!万分小心!
下面的所有方案仅在 Windows 10/11 上成功运行,不保证 Windows 10 以下的版本能够顺利运行。
下面的 Bat 和 PowerShell 都会存在 UTF-8 显示中文时乱码的问题,可以通过更换到 GBK 或 ANSI 编码来解决此问题。

理论

由于本人比较懒,不想每次都跑到设置里来开启/关闭 Windows 的代理,于是写了个脚本并且固定快捷方式到任务栏,就可以进行快速操作了。

众所周知,Windows 的很多设置都对应着一堆注册表值,包括代理设置。

代理设置的注册表:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
  • ProxyEnable:
    对应代理的开关,1为开启0为关闭。
  • ProxyServer:
    对应代理服务器的地址,格式为 “address:port”,例如 “127.0.0.1:443” 或者 “example.com:80″。当地址为域名时,Windows 会自动在前面加上 http://。
  • ProxyOverride:
    对应“请勿对以下列条目开头的地址使用代理服务器。若有多个条目,请使用英文分号 (;) 来分隔”以及“请勿将代理服务器用于本地(Intranet)地址”。如果注册表里没有这一项也正常,因为这两玩意没填的时候 Windows 是不会创建这个注册表项的。另外,“请勿将代理服务器用于本地(Intranet)地址”并不是靠单独的键值来进行开关的。如果开启的话,Windows 会在 ProxyOverride 一栏中添加 “<local>” 这一值。如果填写了“请勿对以下列条目开头的…“这一栏的话,则会将 “<local>” 这一值放在最后面,例如:
192.168.1.*;10.0.*.*;<local>

然后,再通过一个外部配置文件(Config.yaml或者其他啥玩意)并且给这个配置文件创建一个桌面快捷方式,就可以快速编辑代理地址了。另外,再添加一个代理开启或者关闭的通知,完美。

通过批处理脚本(Bat)实现

Bat 脚本使用 Windows 祖传的 msg.exe 来实现,弹窗有点古老。如果想要比较*城市化*的通知,可以参考下面的 PowerShell 的 ps1 脚本,通过 Module 可以实现弹出式通知,就是右下角弹出的那个通知。当然那玩意只能在 Windows 10/11 上使用,Bat 则*比较*通用。

setlocal
::设置成临时变量环境
for /f "usebackq delims=" %%a in ("Config.txt") do set ADDRESS=%%a
::读取 Config.txt 里的内容,并且写成变量
for /f "tokens=1,2,* " %%i in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable ^| find /i "ProxyEnable"') do (set /A ProxyEnableValue=%%k)
::读取注册表,确定代理的状态

if %ProxyEnableValue% equ 0 (
    reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f >nul 2>nul
    reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "%ADDRESS%" /f >nul 2>nul
    msg * /time:5 "代理已开启"
) else if %ProxyEnableValue% equ 1 (
    reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f >nul 2>nul
    reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "" /f >nul 2>nul
    msg * /time:5 "代理已关闭"
)

endlocal
::退出临时变量环境

如上,这玩意需要在 Bat 脚本的同级目录下手动建一个 Config.txt,然后脚本会读取这个文本文档里的内容,具体格式为 “address:port”,例如 “127.0.0.1:443” 或者 “example.com:80”(没错就和上面一样)。这个脚本没有实现 “ProxyOverride” 的功能,因为我改用 Python 了🫠

通过 Windows Powershell 实现

OK现在来到了城市化环节,由于 Powershell 的尿性,默认这玩意是不允许运行第三方脚本的,需要手动开启一下,方法可以在 cn.bing.com 上找到(主要是我忘记是哪一条了🫠可以在运行 ps1 脚本的时候看看出现的错误,然后根据错误查一下解决方法。或者可以使用下面的 VBS 脚本来启动,就可以直接运行了)另外,这个脚本引用了 BurntToast 模块来进行通知,所以要先安装这个模块(当然,如果不需要通知的话,在脚本里删掉相关内容就行)在 PowerShell 中运行以下指令安装 BurntToast 模块:

Install-Module -Name BurntToast

安装之后就可以写脚本了,创建一个 xxx.ps1 ,写入以下内容:

# 引用模组 BurntToast
# 用法:New-BurntToastNotification -AppLogo "Logo图片路径" -Text "标题", "正文"
Import-Module BurntToast

# 定义配置文件的路径,顺便给配置文件内容设个变量
$FilePath = ".\Config.yml"
$Config = Get-Content -Path $FilePath

# 给下面会用到的几个变量先定义空值,防止因为找不到某个变量导致脚本运行到一半然后当场暴毙
$ProxyServer = ""
$ProxyOverride = ""
$NoticeImage = ""

foreach ($line in $Config) 
{
    $line = $line.Trim()

    if ($line -like "#*" -or [string]::IsNullOrWhiteSpace($line))
    {
        continue
    }

    if ($line -like "ProxyServer: *")
    {
        $ProxyServer = $line -replace "ProxyServer: *", ""
        $ProxyServer = $ProxyServer.Trim('"')
    }
    elseif ($line -like "ProxyOverride: *")
    {
        $ProxyOverride = $line -replace "ProxyOverride: *", ""
        $ProxyOverride = $ProxyOverride.Trim('"')
    }
    elseif ($line -like "NoticeImage: *")
    {
        $NoticeImage = $line -replace "NoticeImage: *", ""
        $NoticeImage = $NoticeImage.Trim('"')
    }
}

# 从注册表里读取代理服务器的状态
$ProxyStatus = Get-ItemPropertyValue -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable

# 根据从注册表里读取到的代理状态来进行配置,如果是0,就开启代理;如果是1,就关闭代理
if ($ProxyStatus -eq 0)
{
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable -Value 1
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyServer -Value $ProxyServer
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyOverride -Value "$ProxyOverride"
    New-BurntToastNotification -AppLogo "$NoticeImage" -Text "Windows 网络代理", "状态:已开启", "地址:$ProxyServer"
}
elseif ($ProxyStatus -eq 1) 
{
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable -Value 0
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyServer -Value ""
    Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyOverride -Value ""
    New-BurntToastNotification -AppLogo "$NoticeImage" -Text "Windows 网络代理", "状态:已关闭"
}

接下来在同级目录下创建一个 Config.yml(注意大小写)(本来想在 PowerShell 里面使用 yaml 解释器模块的,但是考虑到这样又要安装新的模块就放弃了,改用读取到#和空行就跳过该行,然后匹配关键字的方式来提取内容并且转换成变量。所以最好不要在配置文件里添加新的内容,防止出现什么奇怪的问题),并且写入以下内容:

# 代理服务器地址
ProxyServer: "127.0.0.1:443"

# 不代理下列条目开头的地址,有多个项目则使用英文分号进行分隔
#例如:localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>
ProxyOverride: "<local>"

# 弹出通知的图片路径,最好是同级,例如.\Image.png
# 如果不指定的话就设置为空,即NoticeImage: "",不要删除下面这一条目,否则可能出现奇怪的问题
NoticeImage: ".\Image.png"

这样就完成了本体。然而,由于 PowerShell 的尿性,ps1的默认打开方式是记事本或者 IDE,所以可以手动把打开方式设置为 PowerShell,或者创建一个 VBS 脚本来启动(这里推荐创建 VBS 脚本,注意要和 ps1 脚本同级),在 xxx.vbs 中写入以下内容:

Dim shell
Set shell = CreateObject("WScript.Shell")
shell.Run "cmd.exe /c powershell -ExecutionPolicy Bypass -File "".\xxx.ps1""", 0, True
Set shell = Nothing

现在就可以通过创建的 VBS 脚本来运行 ps1 脚本,然后配置代理了。可以在桌面创建快捷方式或者固定到任务栏,方便快速切换。

通过 Python 实现(推荐)

虽然通过 Python 脚本实现需要 Python 环境,但是 Python 脚本可以打包成 exe 文件,打包后只有两个文件,AutoProxy.exe和Config.yaml,下载就可以直接使用:Gloxina Cloud

由于包含了 Yaml 解释器和 Plyer 通知模块,这玩意的体积高达 7.73 MB 🫠但是比 PowerShell 和 Bat 都简洁那么一点点。下面是原始的 Python 代码:

# coding=utf-8

import os
import yaml
import winreg as reg
from plyer import notification
import threading

def show_notification(title, message):
    notification.notify(
        title=title,
        message=message,
        timeout=10
    )

file_path = r"./Config.yaml"
with open(file_path, 'r', encoding='utf-8') as file:
    config = yaml.safe_load(file)

proxy_server = config.get("ProxyServer", "").strip('"')
proxy_override = config.get("ProxyOverride", "").strip('"')

key_path = r"Software\Microsoft\Windows\CurrentVersion\Internet Settings"
with reg.OpenKey(reg.HKEY_CURRENT_USER, key_path) as key:
    proxy_status, _ = reg.QueryValueEx(key, "ProxyEnable")

if proxy_status == 0:
    with reg.OpenKey(reg.HKEY_CURRENT_USER, key_path, 0, reg.KEY_SET_VALUE) as key:
        reg.SetValueEx(key, "ProxyEnable", 0, reg.REG_DWORD, 1)
        reg.SetValueEx(key, "ProxyServer", 0, reg.REG_SZ, proxy_server)
        reg.SetValueEx(key, "ProxyOverride", 0, reg.REG_SZ, proxy_override)
    threading.Thread(target=show_notification, args=("Windows 网络代理", f"状态:已启动\n地址:{proxy_server}")).start()
elif proxy_status == 1:
    with reg.OpenKey(reg.HKEY_CURRENT_USER, key_path, 0, reg.KEY_SET_VALUE) as key:
        reg.SetValueEx(key, "ProxyEnable", 0, reg.REG_DWORD, 0)
        reg.SetValueEx(key, "ProxyServer", 0, reg.REG_SZ, "")
        reg.SetValueEx(key, "ProxyOverride", 0, reg.REG_SZ, "")
    threading.Thread(target=show_notification, args=("Windows 网络代理", "状态:已关闭")).start()

Config.yaml 中的内容:

# 代理服务器地址
ProxyServer: "127.0.0.1:443"

# 不代理下列条目开头的地址,有多个项目则使用英文分号进行分隔
# localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*
ProxyOverride: "<local>"

总结

推荐使用 Python 方案。如果需要使用 Bat 或者 PowerShell 方案,可能会存在编码问题,如果使用 UTF-8 编码保存并运行的话,大概率会出现中文显示异常的问题。这时候可以通过转换成 ANSI 或者 GBK 编码来解决此问题(脚本和配置文件都要改,使用相同的编码

发表回复

textsms
account_circle
email

Gloxina

通过脚本快速配置 Windows 代理
太长不看版 下载即可使用,包含 AutoProxy.exe 和 Config.yaml,在 Config.yaml 中进行配置后双击运行 exe 文件即可开启/关闭代理,可以通过下面的 .py 源码自行构建 exe 程序。下载地…
扫描二维码继续阅读
2024-07-19