WindowsProxyManager.dart 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import 'dart:ffi';
  2. import 'dart:io';
  3. import 'package:ffi/ffi.dart';
  4. class WindowsProxyManager {
  5. final DynamicLibrary _winInet = DynamicLibrary.open("wininet.dll");
  6. late final int Function(int, int, Pointer<Void>, Pointer<Uint32>) _internetQueryOption;
  7. late final int Function(int, int, Pointer<Void>, int) _internetSetOption;
  8. WindowsProxyManager() {
  9. _initializeFunctions();
  10. }
  11. void _initializeFunctions() {
  12. _internetQueryOption = _winInet
  13. .lookup<NativeFunction<Int32 Function(IntPtr, Uint32, Pointer<Void>, Pointer<Uint32>)>>(
  14. 'InternetQueryOptionW')
  15. .asFunction();
  16. _internetSetOption = _winInet
  17. .lookup<NativeFunction<Int32 Function(IntPtr, Uint32, Pointer<Void>, Uint32)>>(
  18. 'InternetSetOptionW')
  19. .asFunction();
  20. }
  21. bool isProxyEnabled() {
  22. final optionList = calloc<INTERNET_PER_CONN_OPTION_LIST>();
  23. optionList.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
  24. optionList.ref.dwOptionCount = 1;
  25. optionList.ref.dwOptionError = 0;
  26. final options = calloc<INTERNET_PER_CONN_OPTION>(1);
  27. options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;
  28. optionList.ref.pOptions = options;
  29. final optionSize = calloc<Uint32>()..value = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
  30. final result = _internetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, optionList.cast<Void>(), optionSize);
  31. bool isEnabled = false;
  32. if (result != 0) {
  33. isEnabled = options[0].Value.dwValue != 0;
  34. } else {
  35. print("检测代理状态失败。");
  36. }
  37. calloc.free(optionList);
  38. calloc.free(options);
  39. calloc.free(optionSize);
  40. return isEnabled;
  41. }
  42. void setSystemProxy(String proxyServer, {String bypassList = ""}) {
  43. final proxyInfo = calloc<INTERNET_PER_CONN_OPTION_LIST>();
  44. proxyInfo.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
  45. proxyInfo.ref.dwOptionCount = 3; // 设置为3个选项
  46. proxyInfo.ref.dwOptionError = 0;
  47. // 分配三个选项的空间
  48. final options = calloc<INTERNET_PER_CONN_OPTION>(3);
  49. // 启用代理
  50. options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;
  51. options[0].Value.dwValue = 1; // 1 表示启用代理
  52. // 设置代理服务器
  53. options[1].dwOption = INTERNET_OPTION_PROXY_SERVER;
  54. options[1].Value.pszValue = proxyServer.toNativeUtf16();
  55. // 设置绕过列表
  56. options[2].dwOption = INTERNET_OPTION_PROXY_BYPASS;
  57. options[2].Value.pszValue = bypassList.toNativeUtf16();
  58. proxyInfo.ref.pOptions = options;
  59. // 调用 API 设置代理
  60. final result = _internetSetOption(
  61. 0,
  62. INTERNET_OPTION_PER_CONNECTION_OPTION,
  63. proxyInfo.cast<Void>(),
  64. proxyInfo.ref.dwSize,
  65. );
  66. if (result != 0) {
  67. _internetSetOption(0, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0);
  68. _internetSetOption(0, INTERNET_OPTION_REFRESH, nullptr, 0);
  69. print("系统代理已设置为: $proxyServer");
  70. } else {
  71. print("设置代理失败。");
  72. }
  73. // 释放内存
  74. calloc.free(proxyInfo);
  75. calloc.free(options[1].Value.pszValue); // 只释放字符串指针
  76. calloc.free(options[2].Value.pszValue); // 只释放字符串指针
  77. calloc.free(options);
  78. }
  79. void disableSystemProxy() {
  80. final proxyInfo = calloc<INTERNET_PER_CONN_OPTION_LIST>();
  81. proxyInfo.ref.dwSize = sizeOf<INTERNET_PER_CONN_OPTION_LIST>();
  82. proxyInfo.ref.dwOptionCount = 1;
  83. proxyInfo.ref.dwOptionError = 0;
  84. final options = calloc<INTERNET_PER_CONN_OPTION>(1);
  85. // 禁用代理
  86. options[0].dwOption = INTERNET_OPTION_PROXY_ENABLE;
  87. options[0].Value.dwValue = 0;
  88. proxyInfo.ref.pOptions = options;
  89. final result = _internetSetOption(
  90. 0,
  91. INTERNET_OPTION_SETTINGS_CHANGED,
  92. proxyInfo.cast<Void>(),
  93. proxyInfo.ref.dwSize,
  94. );
  95. if (result != 0) {
  96. _internetSetOption(0, INTERNET_OPTION_REFRESH, nullptr, 0);
  97. print("系统代理已禁用");
  98. } else {
  99. print("禁用代理失败。");
  100. }
  101. calloc.free(proxyInfo);
  102. calloc.free(options);
  103. }
  104. }
  105. // INTERNET_PER_CONN_OPTION_LIST 结构定义
  106. base class INTERNET_PER_CONN_OPTION_LIST extends Struct {
  107. @Uint32()
  108. external int dwSize;
  109. @IntPtr()
  110. external int pszConnection;
  111. @Uint32()
  112. external int dwOptionCount;
  113. @Uint32()
  114. external int dwOptionError;
  115. external Pointer<INTERNET_PER_CONN_OPTION> pOptions;
  116. }
  117. base class INTERNET_PER_CONN_OPTION extends Struct {
  118. @Uint32()
  119. external int dwOption;
  120. external INTERNET_PER_CONN_OPTION_Union Value;
  121. }
  122. base class INTERNET_PER_CONN_OPTION_Union extends Union {
  123. @Uint32()
  124. external int dwValue;
  125. external Pointer<Utf16> pszValue;
  126. }
  127. // 常量定义
  128. const INTERNET_OPTION_PROXY_ENABLE = 3;
  129. const INTERNET_OPTION_PROXY_SERVER = 2;
  130. const INTERNET_OPTION_PROXY_BYPASS = 3;
  131. const INTERNET_OPTION_SETTINGS_CHANGED = 39;
  132. const INTERNET_OPTION_REFRESH = 37;
  133. const INTERNET_OPTION_PER_CONNECTION_OPTION = 75;
  134. // void main() {
  135. // if (Platform.isWindows) {
  136. // final proxyManager = WindowsProxyManager();
  137. //
  138. // // 检测当前系统代理状态
  139. // bool isProxyEnabled = proxyManager.isProxyEnabled();
  140. // print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
  141. //
  142. // // 设置系统代理
  143. // proxyManager.setSystemProxy("http=127.0.0.1:8888;https=127.0.0.1:8888", bypassList: "<local>");
  144. //
  145. // // 再次检测代理状态
  146. // isProxyEnabled = proxyManager.isProxyEnabled();
  147. // print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
  148. //
  149. // // 禁用系统代理
  150. // proxyManager.disableSystemProxy();
  151. //
  152. // // 最后检测代理状态
  153. // isProxyEnabled = proxyManager.isProxyEnabled();
  154. // print("系统代理启用状态: ${isProxyEnabled ? "已启用" : "未启用"}");
  155. // } else {
  156. // print("该代码仅支持 Windows 平台.");
  157. // }
  158. // }