“局域網設置”里有自動配置、代理服務器的設置項目,在進行網絡通訊相關的開發時,需要使用到它們,下邊介紹如何將這些設置信息讀取出來。
當“使用自動配置腳本”不使用時,使用WinHttpGetIEProxyConfigForCurrentUser函數來獲取用戶的代理配置。如果發現用戶使用了自動配置腳本,那么就需要使用API
WinHttpGetProxyForUrl去獲取某個url對應的代理。獲取到代理之后需要考慮:1、是否需要拆分http、https、ftp、socks;2、hostname是否在“例外”中,需要考慮bypass有"<local>"的處理。
補充:使用自動配置腳本(也就是使用PAC文件)注意:1、IE設置里的pac文件路徑不能是本地磁盤路徑,否則WinHttpGetProxyForUrl函數無法正確執行;2、WinHttpGetProxyForUrl的第二個參數必須是http/https開頭的完整路徑。
核心API就僅僅是WinHttpGetIEProxyConfigForCurrentUser和WinHttpGetProxyForUrl,可以在chromium中搜索這兩關鍵函數獲取chromium的實現代碼。
我使用的部分代碼:
std::wstring CIEProxy::GetIEProxy( const std::wstring& strURL, const E_proxy_type& eProxyType ) { std::wstring strRet_cswuyg; WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = {0}; WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig = {0}; BOOL bAutoDetect = FALSE; //“自動檢測設置”,但有時候即便選擇上也會返回0,所以需要根據url判斷 if(::WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig)) { if(ieProxyConfig.fAutoDetect) { bAutoDetect = TRUE; } if( ieProxyConfig.lpszAutoConfigUrl != NULL ) { bAutoDetect = TRUE; autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl; } } else { // error return strRet_cswuyg; } if(bAutoDetect) { if (autoProxyOptions.lpszAutoConfigUrl != NULL) { autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; } else { autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; } autoProxyOptions.fAutoLogonIfChallenged = TRUE; HINTERNET hSession = ::WinHttpOpen(0, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC); if (hSession != NULL) { WINHTTP_PROXY_INFO autoProxyInfo = {0}; bAutoDetect = ::WinHttpGetProxyForUrl(hSession, strURL.c_str(), &autoProxyOptions, &autoProxyInfo); if (hSession!= NULL) { ::WinHttpCloseHandle(hSession); } if(autoProxyInfo.lpszProxy) { if (autoProxyInfo.lpszProxyBypass == NULL || CheckPassBy(strURL, autoProxyInfo.lpszProxyBypass)) { std::wstring strProxyAddr = autoProxyInfo.lpszProxy; strRet_cswuyg = GetProxyFromString(eProxyType, strProxyAddr); } if(autoProxyInfo.lpszProxy != NULL) { GlobalFree(autoProxyInfo.lpszProxy); } if(autoProxyInfo.lpszProxyBypass !=NULL) { GlobalFree(autoProxyInfo.lpszProxyBypass); } } } } else { if(ieProxyConfig.lpszProxy != NULL) { if(ieProxyConfig.lpszProxyBypass == NULL || CheckPassBy(strURL, ieProxyConfig.lpszProxyBypass)) { std::wstring strProxyAddr = ieProxyConfig.lpszProxy; strRet_cswuyg = GetProxyFromString(eProxyType, strProxyAddr); } } } if(ieProxyConfig.lpszAutoConfigUrl != NULL) { ::GlobalFree(ieProxyConfig.lpszAutoConfigUrl); } if(ieProxyConfig.lpszProxy != NULL) { ::GlobalFree(ieProxyConfig.lpszProxy); } if(ieProxyConfig.lpszProxyBypass != NULL) { ::GlobalFree(ieProxyConfig.lpszProxyBypass); } return strRet_cswuyg; }
插入:WinHTTP部分,WinHttpGetDefaultProxyConfiguration 用於從注冊表獲取WinHTTP的代理設置。這個代理設置是通過WinHttpSetDefaultProxyConfiguration或者ProxyCfg.exe設置的。跟IE代理不同。
參考:
1、chromium源碼:
chromium/src/net/proxy/proxy_resolver_winhttp.cc
chromium/src/net/proxy/proxy_config.cc
chromium/src/net/proxy/proxy_bypass_rules.h
2、MSDN:
3、零碎資源:
http://stackoverflow.com/questions/202547/how-do-i-find-out-the-browsers-proxy-settings
http://www.cnblogs.com/chang290/archive/2013/01/12/2857426.html