Go语言设置windows系统代理
package main
import (
"flag"
"fmt"
"syscall"
"unsafe"
)
const (
INTERNET_PER_CONN_FLAGS = 1
INTERNET_PER_CONN_PROXY_SERVER = 2
INTERNET_PER_CONN_PROXY_BYPASS = 3
INTERNET_OPTION_REFRESH = 37
INTERNET_OPTION_SETTINGS_CHANGED = 39
INTERNET_OPTION_PER_CONNECTION_OPTION = 75
)
/*
typedef struct {
DWORD dwOption;
union {
DWORD dwValue;
LPSTR pszValue;
FILETIME ftValue;
} Value;
} INTERNET_PER_CONN_OPTIONA, *LPINTERNET_PER_CONN_OPTIONA;
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
*/
type INTERNET_PER_CONN_OPTION struct {
dwOption uint32
dwValue uint64 // 注意 32位 和 64位 struct 和 union 内存对齐
}
type INTERNET_PER_CONN_OPTION_LIST struct {
dwSize uint32
pszConnection *uint16
dwOptionCount uint32
dwOptionError uint32
pOptions uintptr
}
func SetProxy(proxy string) error {
winInet, err := syscall.LoadLibrary("Wininet.dll")
if err != nil {
return fmt.Errorf(fmt.Sprintf("LoadLibrary Wininet.dll Error: %s", err))
}
InternetSetOptionW, err := syscall.GetProcAddress(winInet, "InternetSetOptionW")
if err != nil {
return fmt.Errorf(fmt.Sprintf("GetProcAddress InternetQueryOptionW Error: %s", err))
}
options := [3]INTERNET_PER_CONN_OPTION{}
options[0].dwOption = INTERNET_PER_CONN_FLAGS
if proxy == "" {
options[0].dwValue = 1
} else {
options[0].dwValue = 2
}
options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER
options[1].dwValue = uint64(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(proxy))))
options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS
options[2].dwValue = uint64(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("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.*;172.32.*;192.168.*"))))
list := INTERNET_PER_CONN_OPTION_LIST{}
list.dwSize = uint32(unsafe.Sizeof(list))
list.pszConnection = nil
list.dwOptionCount = 3
list.dwOptionError = 0
list.pOptions = uintptr(unsafe.Pointer(&options))
// https://www.cnpython.com/qa/361707
callInternetOptionW := func(dwOption uintptr, lpBuffer uintptr, dwBufferLength uintptr) error {
r1, _, err := syscall.Syscall6(InternetSetOptionW, 4, 0, dwOption, lpBuffer, dwBufferLength, 0, 0)
if r1 != 1 {
return err
}
return nil
}
err = callInternetOptionW(INTERNET_OPTION_PER_CONNECTION_OPTION, uintptr(unsafe.Pointer(&list)), uintptr(unsafe.Sizeof(list)))
if err != nil {
return fmt.Errorf("INTERNET_OPTION_PER_CONNECTION_OPTION Error: %s", err)
}
err = callInternetOptionW(INTERNET_OPTION_SETTINGS_CHANGED, 0, 0)
if err != nil {
return fmt.Errorf("INTERNET_OPTION_SETTINGS_CHANGED Error: %s", err)
}
err = callInternetOptionW(INTERNET_OPTION_REFRESH, 0, 0)
if err != nil {
return fmt.Errorf("INTERNET_OPTION_REFRESH Error: %s", err)
}
return nil
}
func main() {
proxy := flag.String("p", "127.0.0.1:10809", "(-p host:port 设置并启用代理服务器, -p c 取消设置")
flag.Parse()
if *proxy == "c" {
if err := SetProxy(""); err == nil {
fmt.Println("取消代理设置成功!")
} else {
fmt.Printf("取消代理设置失败: %s\n", err)
}
} else {
if err := SetProxy(*proxy); err == nil {
fmt.Printf("设置代理服务器: %s 成功!\n", *proxy)
} else {
fmt.Printf("设置代理服务器: %s 失败, : %s\n", *proxy, err)
}
}
}
C#语言设置windows系统代理
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace proxysetting
{
public class ProxyManager
{
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lPBuffer, int lpdwBufferLength);
private const int INTERNET_OPTION_REFRESH = 0x000025;
private const int INTERNET_OPTION_SETTINGS_CHANGED = 0x000027;
private const string regeditKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
private List<string> proxyLibs = new List<string>();
private void Reflush()
{
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_SETTINGS_CHANGED, IntPtr.Zero, 0);
InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0);
}
public void Add(string server)
{
this.proxyLibs.Add(server);
}
public void Run()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(regeditKey, true);
key.SetValue("ProxyServer", String.Join(";", this.proxyLibs.ToArray()));
key.SetValue("ProxyEnable", 1);
key.Close();
this.Reflush();
}
public void Stop()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(regeditKey, true);
key.SetValue("ProxyEnable", 0);
key.Close();
this.Reflush();
}
}
}
封装至主程序:
namespace proxysetting
{
class Program
{
static void Main(string[] args)
{
var pm = new ProxyManager();
if (args.Length < 1) return;
if (args[0] == "stop")
{
pm.Stop();
}
else
{
for (var i = 0; i < args.Length; i++)
{
pm.Add(args[i]);
}
pm.Run();
}
}
}
}
通过命令行传递参数调用:
# 设置http和https代理,代理ip为127.0.0.1,端口号17173
proxysetting http=127.0.0.1:17173 https=127.0.0.1:17173
# 取消代理
proxysetting stop
修改注册表设置windows系统代理
控制系统代理的2个注册表:
计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable
计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer
代码实现(无法立即生效,可能要重启电脑):
package main
import (
"bytes"
"encoding/binary"
"flag"
"fmt"
"os"
"os/exec"
"golang.org/x/sys/windows/registry"
)
var setproxy string
var unsetproxy bool
func main() {
var err error
flag.StringVar(&setproxy, "setproxy", "", "set sys proxy")
flag.BoolVar(&unsetproxy, "unsetproxy", false, "unset sys proxy")
flag.Parse()
if setproxy != "" {
err = setProxy(setproxy)
if err != nil {
fmt.Println("设置代理失败:", err)
panic(err)
}
fmt.Println("代理已设置:", setproxy)
return
}
if unsetproxy {
// 取消代理
err = unsetProxy()
if err != nil {
fmt.Println("取消代理失败:", err)
panic(err)
}
fmt.Println("代理已取消")
}
}
func getRegistryKey() (k registry.Key, err error) {
registryKeyPath := `Software\Microsoft\Windows\CurrentVersion\Internet Settings`
k, exist, err := registry.CreateKey(registry.CURRENT_USER, registryKeyPath, registry.ALL_ACCESS)
if err != nil {
return k, err
}
if !exist {
panic(registryKeyPath + "not existed")
}
return k, nil
}
func setProxy(proxyAddress string) error {
k, err := getRegistryKey()
if err != nil {
return err
}
defer k.Close()
// 设置代理
err = k.SetStringValue("ProxyServer", proxyAddress)
if err != nil {
return err
}
// 启用代理
// err = k.SetBinaryValue("ProxyEnable", IntToBytes(1))
err = k.SetDWordValue("ProxyEnable", 1)
if err != nil {
return err
}
return refreshProxy()
}
func refreshProxy() error {
var err error
// 刷新系统代理设置
// InetCpl.cpl 出错 丢失条目: ProxyRunDll
cmd := exec.Command("Rundll32.exe", "InetCpl.cpl,ProxyRunDll")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
return err
}
return nil
}
func unsetProxy() error {
// 禁用代理
k, err := getRegistryKey()
if err != nil {
return err
}
defer k.Close()
// err = k.SetBinaryValue("ProxyEnable", IntToBytes(0))
err = k.SetDWordValue("ProxyEnable", 0)
if err != nil {
return err
}
return refreshProxy()
}
func IntToBytes(n int) []byte {
x := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, x)
return bytesBuffer.Bytes()
}
Golang sysproxy https://blog.csdn.net/q1009020096/article/details/108181729
Golang 调用WinAPI 修改代理 https://blog.csdn.net/leoforbest/article/details/120166881
使用程序修改系统(IE)代理设置 https://www.cnblogs.com/honghongming/archive/2014/01/24/3532567.html
用代码为windows设置代理(修改注册表)https://codeleading.com/article/29115078136/
Go 命令行桌面版设置代理(可能是AI生成的,代码跑不了,Rundll32.exe命令也报错) https://www.jianshu.com/p/d2cf825ce93b