我我的在平常使用電腦時,常常須要使用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