“局域网设置”里有自动配置、代理服务器的设置项目,在进行网络通讯相关的开发时,需要使用到它们,下边介绍如何将这些设置信息读取出来。
当“使用自动配置脚本”不使用时,使用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