2008-10-14 145 views
24

我正在为Windows编写一个命令行工具,它使用libcurl从互联网上下载文件。如何找出浏览器的代理设置?

很明显,当用户在代理服务器后面时,下载不起作用,因为代理需要配置。然而,我想让我的工具尽可能简单,并且不必为用户配置代理服务器造成负担。我的工具甚至没有配置文件,所以用户必须在每个命令中传递代理设置,或者设置一个环境变量或者其他方式 - 太麻烦了。

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

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

我怎么去呢?更具体地说:

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

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

+1

[请在此查找代码来获得IE的代理设置。] http://stackoverflow.com/a/12601449/ 559746 – 2012-09-26 12:21:20

回答

33

你正在寻找的功能是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 
    } 
} 
1

这些值有注册表项,当然你可以直接获取这些值。你也可以在.NET中做到这一点,没有任何麻烦。我相信WebClient对象会根据当前设置为您协商代理设置。这看起来像这样在C#中:

using System.Net; 

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

或者其他的东西。

+0

顺便说一下,您还可以使用相同的类来检测代理。有一个GetProxy()方法的Proxy属性。 – 2008-10-14 20:14:19

+0

谢谢,但我使用C,所以这是没有问题的(如果我能避免它,我不想诉诸COM)。我编辑了这个问题来澄清。 – rix0rrr 2008-10-14 21:03:24

0

对于Firefox/Seamonkey的,这个问题是因为许多配置文件存在的有点棘手。

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

我正在研究mozilla的一些文档,所以把你的后续问题放在这里(检查维基盒),我会尽量给你你需要的信息。

3

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

[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); 
    } 
} 
相关问题