Windows 机密等待 RunOnce

Raymond Chen

假设 存在一个需要在进程当中重新启动系统的安装。例如,程序可能想要升级当前正在使用的系统 DLL。您可能需要触发一个干预重新引导以安装新的 DLL 文件,然后,在 DLL 升级完毕后,您可以将其用于安装的下一阶段中。

RunOnce 项便是针对此类场景而开发,在干预重新启动后,安装程序利用它来完成各自的安装(这是过去认为程序不会将事情弄糟的那段日子)。

Windows® Explorer 会在创建桌面和任务栏之前等待 RunOnce 程序的运行,直至完成。这是因为 RunOnce 在支持安装程序的原则下运行。由于 RunOnce 程序可能会更改系统配置数据,所以您不希望用户在重新配置系统期间使用该系统。

例如,RunOnce 程序正在对其刚刚安装的文件执行重定位基址和绑定,其中有些是外壳扩展的一部分。您当然不希望用户在程序或扩展的可执行文件仍在更新的同时尝试运行该程序或激活该扩展吧。

“支持安装程序”原则的另一个缺陷是仅当具有管理员权限的用户登录时,才会对 RunOnce 项进行处理。因此,不是管理员的用户无法完成安装。除此之外,如果对非管理员执行 RunOnce 项,则它将不再“运行一次”。事实上,这会造成一个进退两难的局面。这时您会怎么说呢,“好吧,我们不再运行它了,我们去运行另外一个”?要改变这一系统全局状态,您需要拥有管理权限。另外,很明显,非管理用户没有管理权限!程序再也不会是“运行一次”,相反地,它会“一次又一次地运行,直到管理员登录为止”。

  (单击该图像获得较大视图)

RunOnce 主要用于结束程序安装,它显示在 Windows 安装程序中。当您试图安装服务包或升级为更新版本的 Windows 系统时,安装向导会检查 RunOnce 项。如果该项非空,您将收到一条错误消息,“程序安装仍在进行中,请先完成安装,然后再尝试升级操作系统。”这是合理的,因为您并不想恰好在程序安装过程当中来更改操作系统。

RunOnce 的整个设计都透露着它的过去。Windows 95,一个未对管理员和非管理员做出区分的操作系统中就有它的印记。实质上,由于每个人都是 Windows 95 的管理员,所以使用 RunOnce 的安装程序会依赖于下次重新启动时所执行的 RunOnce 活动。

对于最新的 Windows 操作系统,具有管理员权限的用户的一次登录时间不得长达数月这个设想将成为可能,对于 Windows Vista™ 尤其是这样。因此,需要运行 RunOnce 的程序可能会在经历过漫长的等待之后才能找到自身。

作为旁观者,我曾经见过一个永久的 RunOnce。每当它运行时,都会将自己重新添加到 RunOnce 项中。这明显违反了 RunOnce 项的初衷,因为它不再是程序安装的一部分,而是程序常规操作的一部分。而且,这种行为会导致 Windows 安装程序将始终报告说,有一个安装正在进行中。

因此,该用户再也不能升级操作系统了,因为这个惹人厌的程序总是在说:“我还需要做一些小事情,马上就可做完”。程序今天不会完成安装,“但是明天一定可以”。这非常类似于等待 Godot,但希望不会有生存危机。

Raymond Chen的网站 The Old New Thing 用于处理 Windows 历史和 Win32 编程。他当前正在编写一本书,恰巧书名也叫《The Old New Thing》(Addison-Wesley,2007)。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.