一个合理的算法是这样的:
尝试使用用户当前的代理设置(IE 使用的代理设置)进行连接。这些是最有可能工作的。请参阅WinHttpGetIEProxyConfigForCurrentUser()
MSDN 以获取这些设置,或参阅INTERNET_OPEN_TYPE_PRECONFIG
WinINet。
如果失败,请尝试直接连接。
如果失败,请尝试使用WinHttpGetProxyForUrl进行 WPAD 自动检测。(WPAD是客户端可以在网络上找到代理自动配置 (PAC)文件的自动化方式,通常是公司网络。)您需要选择选项来检查代理文件的 DHCP 和 DNS。WinHTTP AutoProxy Functions
MSDN 上包含使用此 API 的代码示例和大量支持信息。如果此操作成功,您将取回代理信息,然后您可以将其插入您的 HTTP 下载代码。AFAIK,没有等效的 WinINet 选项可以自动进行新的 WPAD 检测——只有 WinHTTP。
接下来您可以尝试查找 Firefox 代理设置。 此 SO 回答有关这些设置的位置和格式的详细信息,以便您可以以编程方式访问它们。
如果仍然失败,请让用户(在您的 UI 中)检查他们的互联网连接是否实际连接。实际上,与上述所有代理检测步骤失败相比,用户断开连接更为常见。要求用户打开他们的浏览器以确保他们可以访问互联网站点——如果上述步骤失败,他们的浏览器可能无法看到网络。一旦用户声称他们已连接,请重复步骤 1-3。
如果以上所有方法都失败了,你真的别无选择,只能要求用户手动指定他们的代理信息。您可能想要克隆 IE 或 firefox 的代理 UI,并将这些 UI 设置转换为适当的参数,以便在下载该文件时配置代理选项。
请注意,代理检测没有什么魔力——您可以选择使用用户设置、使用默认计算机设置、使用直接连接、使用 WPAD 查找 PAC 文件或询问用户。不幸的是,没有办法“在不需要处理代理的情况下建立 HTTP 连接”。
顺便说一句,尽管您可以仅将 WinHTTP 用于代理检测,然后使用 WinINet 获取文件,但我建议对这两个部分都使用 WinHTTP。当您想要最大的灵活性和对 HTTP 交互的控制(以及比 WinINet 更好的稳定性)时,WinHTTP 是更可取的。
更新 2:
JJ 上面有一个好主意——我添加了一个检查 Firefox 代理设置的步骤。由于奇怪的代理通常存在于公司环境中(倾向于在 IE 上标准化),因此这不太可能有所帮助,但值得一试。
更新:我刚刚编辑了上面的部分以回应弗朗西斯的正确评论:WinHTTP 不是严格意义上的 WinINet 的“继任者”(意味着 WinINet 的 100% 功能在 WinHTTP 中可用)。相反,WinHTTP 是为使用 HTTP 进行数据交换并且不关心与 Internet Explorer 的缓存、cookie、拨号 UI 等集成的应用程序设计的。
服务器应用程序肯定属于这一类(WinHTTP 与 WinINet 不同,在服务器应用程序中使用是安全的)但许多客户端软件也使用它,例如每台现代 PC 上的 Windows Update 客户端。一般来说,WinHTTP 更适合需要通过 HTTP 下载文件、需要对网络进行更细粒度的控制并希望控制自己的 UI 的客户端应用程序。
WinHTTP 更亲力亲为(例如,您需要调用一个 API 来获取代理信息,而另一个调用才能使用该代理信息),但是这种额外程度的控制允许您执行 WinINet 无法执行的操作,例如强制忽略用户的代理设置并尝试新的 WPAD 检测。