我我的在平常使用电脑时,常常须要使用Google,因而就要切换代理,基本上是一下子切换为代理,一下子切换成直连,总是打开internet 选项去设置,很不方便,因而我萌生了一个想法:python
作一个开关,我想用代理的时候,就点一下打开。不想用时,就再点一下关闭。c++
简单的说,就是自动更改IE的代理设置。git
实际上这个功能可使用纯python实现,其核心的原理就是使用 Windows API InternetSetOption。可是python去调用这个api至关复杂,不过人家已经实现过了,参见stackoverflow的问题github
不过话说回来,想调用windows api这件事,为何不适用c/c++来实现呢,这对他们来讲很简单就实现了,绕python一圈感受不是很合理。windows
因此,这一段用c++来写,而后其余地方要调用直接调用就行了,使用c++来更改代理服务器,代码大概长这个样子:api
IEPROXY_API bool setproxy(TCHAR* server, bool enabled) { INTERNET_PER_CONN_OPTION_LIST list; DWORD dwBufSize = sizeof(list); // Fill the list structure. list.dwSize = sizeof(list); // NULL == LAN, otherwise connectoid name. list.pszConnection = nullptr; // Set three options. list.dwOptionCount = 3; list.pOptions = new INTERNET_PER_CONN_OPTION[3]; // Ensure that the memory was allocated. if (nullptr == list.pOptions) { // Return FALSE if the memory wasn't allocated. return false; } // Set flags. list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS; list.pOptions[0].Value.dwValue = enabled ? PROXY_TYPE_PROXY : PROXY_TYPE_DIRECT; // Set proxy name. list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER; list.pOptions[1].Value.pszValue = server; // Set proxy override. list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS; list.pOptions[2].Value.pszValue = TEXT("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.*"); // Set the options on the connection. auto bReturn = InternetSetOption(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, dwBufSize); if (bReturn) { InternetSetOption(nullptr, INTERNET_OPTION_SETTINGS_CHANGED, nullptr, 0); InternetSetOption(nullptr, INTERNET_OPTION_REFRESH, nullptr, 0); } // Free the allocated memory. delete[] list.pOptions; return bReturn; }
看起来代码有点长,其实有用的就那么两三行而已。服务器
总之,c++部分的代码作好,编译,最后生成一个dll,用dependency walker打开,里面能看到有三个c函数。ide
下一步才是今天的主题,若是用python再调用。函数
尝试一下用ctypes来实现,ctypes提供跟c兼容的数据类型,也容许你调用DLL,你能够用ctypes来封装纯python的api。命令行
它使用起来也特别简单,基本上就只有三句话:
首先引入ctypes,这没必要说了。而后使用cdll.LoadLibrary再装载dll,最后调用dll内部的函数,setproxy就是我以前写的c的函数,上面的图上有。整个过程很天然,很简单。
我最早尝试的是用pyqt来作一个图形的界面,每次都在这个图形界面上打开和关闭代理,但后来以为这也太复杂了,图形化的反而不如命令行简单直接,那不如直接写成命令行的算了,双击脚本a就打开,双击b就关闭,而后把a和b都放在桌面上就行了嘛。
因而乎,就有了下面的两个bat文件:
disable-proxy.bat
python.exe .\setproxy.py --proxy 127.0.0.1:8118 --switch 0
enabled-proxy.bat
python.exe .\setproxy.py --proxy 127.0.0.1:8118 --switch 1
我把这两个bat文件的快捷方式放在桌面上,用的时候双击其中一个就行。
固然了,你都用c写成了一个dll了,那干脆你也写成一个独立的exe算了,exe内部解析命令行。
是的,这样更好了,都不须要python的环境了,不过,下次再写吧。
本文涉及到的源代码在 Github-Syler-Fun