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

  当“使用自动配置脚本”不使用时,使用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

 

 

 

 

posted on 2013-07-01 01:22  烛秋  阅读(7117)  评论(4编辑  收藏  举报