2008-10-14 54 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); 
    } 
} 
相關問題