【问题标题】:How do I find out the browser's proxy settings?如何找出浏览器的代理设置?
【发布时间】:2010-09-17 04:23:18
【问题描述】:

我正在为 Windows 编写一个命令行工具,它使用 libcurl 从 Internet 下载文件。

显然,当用户在代理服务器后面时,下载不起作用,因为需要配置代理。但是,我希望使我的工具尽可能简单,并且不必让用户承担配置代理的负担。我的工具甚至没有配置文件,因此用户必须在每个命令上传递代理设置,或者设置环境变量或诸如此类的东西——太麻烦了。

所以我想,每个人的浏览器通常都已经正确设置,代理配置和一切。即使是最基本的用户也是如此,否则“他们的互联网将无法正常工作”。

所以我想我可以通过查看 IE 的代理设置来确定是否使用代理。

我该怎么做?更具体地说:

  • Windows 中是否有一组“代理设置”,供所有浏览器(可能是 IE)使用,还是我必须为 IE、Firefox、Opera 等编写不同的例程?
  • 我知道如果手动配置这些值,我可能可以直接从相应的注册表位置读取这些值,但这是否也适用于“自动检测代理服务器”?我什至不得不为那个选项而烦恼,还是它(几乎)从未使用过?

在人们开始提出替代方案之前:我正在使用 C,所以我仅限于 Win32 API,我真的很想继续使用 C 和 libcurl。

【问题讨论】:

标签: windows internet-explorer firefox proxy browser


【解决方案1】:

这是一个完整的代码示例,如何在 C# 中从 winhttp.dll 库中调用 WinHttpGetIEProxyConfigForCurrentUser 方法

[TestClass]
public class UnitTest1
{
    [StructLayout(LayoutKind.Sequential)]
    public struct WinhttpCurrentUserIeProxyConfig
    {
        [MarshalAs(UnmanagedType.Bool)]
        public bool AutoDetect;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string AutoConfigUrl;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string Proxy;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ProxyBypass;

    }

    [DllImport("winhttp.dll", SetLastError = true)]
    static extern bool WinHttpGetIEProxyConfigForCurrentUser(ref WinhttpCurrentUserIeProxyConfig pProxyConfig);

    [TestMethod]
    public void TestMethod1()
    {
        var config = new WinhttpCurrentUserIeProxyConfig();

        WinHttpGetIEProxyConfigForCurrentUser(ref config);

        Console.WriteLine(config.Proxy);
        Console.WriteLine(config.AutoConfigUrl);
        Console.WriteLine(config.AutoDetect);
        Console.WriteLine(config.ProxyBypass);
    }
}

【讨论】:

    【解决方案2】:

    您正在寻找的函数是 WinHttpGetIEProxyConfigForCurrentUser(),它记录在 http://msdn.microsoft.com/en-us/library/aa384096(VS.85).aspx。默认情况下,Firefox 和 Opera 使用此函数来获取它们的代理设置,尽管您可以在每个浏览器中覆盖它们。不过,不要那样做。正确的做法(其他人都这样做)是获取 IE 设置并假设它们是正确的,因为它们几乎总是正确的。

    以下是相关逻辑的示例,您应该根据自己的需要进行调整:

    if( WinHttpGetIEProxyConfigForCurrentUser( &ieProxyConfig ) )
    {
        if( ieProxyConfig.fAutoDetect )
        {
            fAutoProxy = TRUE;
        }
    
        if( ieProxyConfig.lpszAutoConfigUrl != NULL )
        {
            fAutoProxy = TRUE;
            autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl;
        }
    }
    else
    {
        // use autoproxy
        fAutoProxy = TRUE;
    }
    
    if( fAutoProxy )
    {
        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;
        }
    
        // basic flags you almost always want
        autoProxyOptions.fAutoLogonIfChallenged = TRUE;
    
        // here we reset fAutoProxy in case an auto-proxy isn't actually
        // configured for this url
        fAutoProxy = WinHttpGetProxyForUrl( hiOpen, pwszUrl, &autoProxyOptions, &autoProxyInfo );
    }
    
    if ( fAutoProxy )
    {
        // set proxy options for libcurl based on autoProxyInfo
    }
    else
    {
        if( ieProxyConfig.lpszProxy != NULL )
        {
            // IE has an explicit proxy. set proxy options for libcurl here
            // based on ieProxyConfig
            //
            // note that sometimes IE gives just a single or double colon
            // for proxy or bypass list, which means "no proxy"
        }
        else
        {
            // there is no auto proxy and no manually configured proxy
        }
    }
    

    【讨论】:

    • 这是一个很好的答案,但很可能还有缓存的代理凭据(用户名和密码)需要以某种方式转发到代理服务器,我认为没有用这种技术实现这一目标的方法是什么?
    【解决方案3】:

    对于 Firefox/Seamonkey,由于存在许多配置文件,问题有点棘手。

    如果您想假设只有一个配置文件,那么您只需要找到 prefs.js。您解析 network.proxy.type,然后使用它来决定要读取哪些相关值。

    我正在为 mozilla 编写一些文档,因此请将您的后续问题放在此处(选中 wiki 框),我会尽力为您提供所需的信息。

    【讨论】:

      【解决方案4】:

      当然,您可以直接访问这些值的注册表项。您也可以在 .NET 中轻松完成此操作。我相信 WebClient 对象会根据当前设置为您协商代理设置。这在 C# 中看起来像这样:

      using System.Net;
      
      string url = "http://www.example.com";
      WebClient client = new WebClient();
      byte[] fileBuffer = client.DownloadFile(url);
      

      或类似的东西。

      【讨论】:

      • 顺便也可以使用同一个类来检测代理。有一个带有 GetProxy() 方法的 Proxy 属性。
      • 谢谢,但我使用的是 C,所以这是不可能的(如果可以避免的话,我不想求助于 COM)。我已经编辑了问题以澄清。
      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2011-03-04
      • 2012-11-01
      • 2012-11-01
      • 1970-01-01
      • 2017-09-14
      • 2013-02-07
      相关资源
      最近更新 更多