我正在为Windows编写一个命令行工具,它使用libcurl从互联网上下载文件。
显然,当用户在代理服务器后面时,下载不起作用,因为需要配置代理。我希望尽可能简化我的工具,而不必为用户配置代理负担。我的工具甚至没有配置文件,因此用户必须在每个命令上传递代理设置,或者设置环境变量或者某种方式 - 太麻烦了。
所以我想,每个人的浏览器通常都已经正确设置,代理配置和一切。即使是最基本的用户也是如此,否则“他们的互联网将无法正常工作”。
所以我认为我可以通过查看IE的代理设置来了解是否使用代理。
我该如何解决这个问题?更具体地说:
在人们开始建议替代方案之前:我正在使用C,所以我只限于Win32 API,我真的很想继续使用C和libcurl。
答案 0 :(得分:36)
您正在寻找的函数是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 :(得分:3)
以下是如何在C#中从WinHttpGetIEProxyConfigForCurrentUser
库调用winhttp.dll
方法的完整代码示例
[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 :(得分:1)
当然,您可以直接获得这些值的注册表项。您也可以在.NET中完成此操作而不会有太多麻烦。我相信WebClient对象会根据当前设置为您协商代理设置。这在C#中看起来像这样:
using System.Net;
string url = "http://www.example.com";
WebClient client = new WebClient();
byte[] fileBuffer = client.DownloadFile(url);
或者接近那个。
答案 3 :(得分:0)
对于Firefox / Seamonkey,由于存在许多配置文件,问题有点棘手。
如果您想假设只有一个配置文件,那么您只需要找到prefs.js。您解析network.proxy.type,然后使用它来决定要读取哪些相关值。
我正在为mozilla制作一些文档,所以请将您的后续问题放在这里(选中wiki框),我会尽力为您提供所需的信息。