Windows 更新过程对于普通用户基本是无感的,不需要用户参与。系统中的更新服务会自动周期性的检查更新服务器是否有适合本机的更新包,只要连接到互联网并且更新服务器上有适用于客户计算机的更新包,客户计算机就会下载并安装 Windows 更新。
网络代理能够保护用户隐私、提高安全性、访问加速,对于组织单位来说,还能提供网络访问控制、节省带宽,它的使用比较常见。
本来体验丝滑的 Windows Update 更新过程和具有一身优点的网络代理各自安好,但它俩遇到一起想要更进一步的时候,二者合作并不顺畅。给人的感觉就变成了"混乱"的 Windows 10 更新系统代理。
为什么这么说呢?Windows 更新过程涉及扫描、下载、安装过程,每一部分都采用独立的服务。Windows 更新客户端利用 Windows HTTP 服务(WinHTTP)扫描可用更新;利用 Background Intelligent Transfer Service (BITS)服务或者Delivery Optimization (DO)来下载更新。这些服务各自独立,需要针对这些服务进行代理配置,使其能够通过代理完成 Windows 系统更新。再加上不同组策略的影响,当用户为更新系统配置代理的时候,偶尔会出现明明已经开启代理,但更新服务就是没有工作,这不免会产生"混乱"的感觉。
介绍 Windows 10 操作系统在更新过程中使用代理的配置方式之前,本文先从我的理解说明 Windows 更新代理配置实现背后(搞的这么混乱)的原因,如何为 Windows 更新系统配置代理将在《'混乱'的 Windows 10 更新系统代理(下)》中说明。
首先看一下 Windows (无特殊说明,均指 Windows 10)系统中支持哪些代理设置。
Windows 中的代理
Windows 默认支持用户设置代理,包括"用户代理"、"计算机代理"和"系统代理"设置。需要说明一点,三种代理设置方式都不是"全局代理","全局代理"是指 Windows 系统中所有的对外连接都要通过这个代理。Windows 本身没有全局代理的配置,可以借助第三方软件实现。
用户代理
一种说法是采用netsh进行WinHttp代理设置对系统范围内通过WinHttp API实现的http会话都有效,所以这种方式设置的代理就成为了"系统"代理。
这里称为"系统"代理总是容易引起误会,它的最准确称呼应该是WinHttp代理,但这个又有些专业拗口了...
强调一点,这个代理并不是全局的。
基本用法
netsh winhttp set proxy myproxy
set proxy myproxy:80 &#34;<local>bar&#34;
set proxy proxy-server=&#34;http=myproxy;https=sproxy:88&#34; bypass-list=&#34;*.contoso.com&#34;Windows 中代理实现的背后
在开发 Windows 桌面客户端应用时,有几种实现http的方式。开发人员可以自己封装 Winsock 来支持http的实现,这具有灵活性和扩展性,但随之而来的问题是工作量大、开发效率低。可以采用第三方库,如libcurl、boost,它们提供了跨平台的优势,但会引入额外第三方代码,可能带来license风险。还有就是微软提供了非常多的和比较细分的网络服务、库和开发框架供开发人员使用,其中就包括 Windows Internet(WinInet) 和 Microsoft Windows HTTP Services(WinHttp) 服务。
WinNet使应用程序能够与 FTP 和 HTTP 协议交互以访问 Internet 资源。WinHttp提供HTTP客户端应用程序编程接口,以使通过HTTP协议将请求发送到其他HTTP服务器。二者都能够提供对HTTP访问的支持,但它们存在的区别决定了我们使用一些网络服务时候看到的不同现象。
WinINet
WinINet 从 Windows NT 和 Windows 95 开始就存在了,它的主要目的是允许应用程序与FTP和HTTP协议交互来访问网络资源。官方不建议WinINet用在 Windows Service 和服务器应用中[2],它主要被IE和其他一些需要网络连接的应用使用。
通过process explorer工具可以查看使用WinINet.dll的应用程序,IE是其中之一。
2. WinINet支持凭据管理
这里的凭据管理包括两个部分&#34;凭据缓存&#34;和&#34;凭据提示&#34;。
Credential Cache, Allows all built-in applications in Windows Internet Explorer to get credentials automatically. It also allows an application running outside of Internet Explorer to prompt/specify the credentials for the server only once. From then on the requests are automatic.
Credential Prompting, Provides an API that allows the calling code to prompt the user for credentials.上面是官方给的说法,说白了就是WinINet支持http会话中服务器身份验证和代理身份验证,并且能够以交互的方式要求用户输入身份验证凭据(即用户名和口令)。身份验证分为两种情况:代理服务器对用户连接请求的认证;(真实)服务器对用户登录的认证[4]。
按照HTTP协议文档(RFC2616)建议,当服务器收到需要身份验证的请求时,服务器将返回 401 状态代码消息;当客户端尝试使用需要身份验证的代理时,代理会将 407 状态代码消息返回到客户端。在IE浏览器中访问这两种需要认证的服务的时候,就会弹出对话框,要求输入认证的信息。基本的认证方式就是要求输入用户名和口令。这个过程就是对应&#34;凭据提示&#34;。
在用户输入完成后,这个凭据会被缓存,当下次请求相同的地址需要认证的时候,&#34;凭据缓存&#34;就会发生作用。
被缓存的凭据可以通过系统中的&#34;凭据管理器&#34;中查看。
WinHttp
WinHttp 支持服务器应用程序、Windows 服务和 Windows 应用程序开发。
通过process explorer工具可以查看使用WinHttp.dll的应用程序。
WinHttp应用作为普通用户程序运行的时候,如果代码逻辑中支持对代理的检查,它是可以使用用户代理进行网络访问的,也就是WinHttp应用也支持使用IE代理。
WinHttp应用作为 Windows 服务运行的时候,是以Local System Account运行,此时不能够访问HKEY_CURRENT_USER下面的注册表项。因为这个限制,用户代理中配置的代理信息就无法使用了。需要使用netsh来配置&#34;系统&#34;代理,使其对于系统中所有调用WinHttp API应用都生效。
两种运行环境下,WinHttp都能够支持代理设置。但与WinINet相比,WinHttp不支持凭据管理,当代理或应用服务器要求用户认证的时候,WinHttp无法满足要求。
至此,Windows 中的代理分类及基本的配置已经介绍完毕,在下一部分,我们介绍这些代理配置是如何影响 Windows 更新过程的。
参考
internet explorer downloads
WinInet is not supported in a service or an IIS application
WinINet vs. WinHTTP
Handling Authentication
参考
^internet explorer downloads https://support.microsoft.com/en-us/windows/internet-explorer-downloads-d49e1f0d-571c-9a7b-d97e-be248806ca70#ID0EBBD=Windows_10
^WinInet is not supported in a service or an IIS application https://learn.microsoft.com/en-US/troubleshoot/developer/browsers/development-website/wininet-not-supported-in-services
^WinINet vs. WinHTTP https://learn.microsoft.com/en-us/windows/win32/wininet/wininet-vs-winhttp