Windows 安装包时避免 FileinUse 对话框

Windows Installer-Avoid FileinUse dialog box when Installing a package

当有文件的更新补丁必须用现有文件替换时,如果任何进程正在使用其中一个文件,则会弹出一个正在使用的文件对话框-up.I 想要避免该对话框并让该文件排队等待安装,以便可以在系统重新启动时安装它。 我读到在重新启动时排队更新文件是 windows 安装程序的内置功能。 有人可以建议我删除该 FileInUse 对话框的方法。 我尝试将 "MsiRMFilesInUse" 属性 设置为“0”,但没有成功。

“简短”答案

Essentially: you could 1) run completely silently (suppresses the files-in-use dialog), 2) shut down locking applications gracefully (application update to allow graceful shutdown - with or without restart manager support), 3) ensure proper service control (if dealing with services), 4) force-kill running processes (the "sledgehammer-approach"), 5) abort setup if locks are detected, 6) require logoff before deployment, 7) install to a new folder for each version (side-by-side install), etc...

下面是对文件使用问题Restart Manager的一些深入分析——旨在快速查看文件使用和重启问题。

就你的实际问题而言。我不会乱用 FileInUse dialog(s)。它不会真正解决你的问题。也许考虑这些指针:

  • 服务:如果您正在安装服务并且它们触发文件使用中的问题,请参阅底部的服务部分以确定您是否可以改进设置的逻辑。
  • 静默模式:运行您在静默模式下的设置将是抑制此类文件的明显方法-使用对话框,但是你必须禁止自动重启,否则系统会在没有警告的情况下自发重启。详情如下。
  • 政策:请检查您的机器/标准 PC 配置是否启用了 DisableAutomaticApplicationShutdown policy。请参阅下面的详细信息。
    • 注册表位置是:HKLM\Software\Policies\Microsoft\Windows\Installer.
    • 我不确定启用此策略是否会使正在使用的文件对话框消失。
  • Restart Manager Compliance:也许检查您是否应该更新您的应用程序以注意 Restart Manager feature 的设计 - 到允许通过应用程序优雅地自行关闭来进行自动魔术和无问题升级(前提是您正在处理实际上可以自己更改的二进制文件 - 换句话说:您拥有源代码)。 下面有很多细节
  • "Setup Overkill":如果您认为在升级过程中可以毫不留情地终止您的应用程序是安全的,请参阅下面的部分。
  • Graceful Shutdown Custom Action:如果你让你的应用程序能够正常关闭(重启管理器风格),那么你可以触发通过即时模式自定义操作(如果重新启动管理器被策略禁用 - 不过要注意时间和超时问题 - 特别是对于静默 运行ning - “死锁” ").
  • 并行安装:下面是一些细节。一些公司决定真正并行安装应用程序,这样他们的新部署就不会出现文件覆盖问题(尽管卸载旧版本可能仍会触发所需的重启)。

我想如果检测到锁定的文件,您也可以中止安装,或者您可以要求用户在安装前注销是 运行 - 如果你有一个分配系统。

请至少浏览其余答案以了解更多详细信息和上下文。


重新启动管理器

您的应用程序和服务应准备好由 Restart Manager 关闭并保存干净重启所需的用户数据和状态信息。这需要对应用程序/服务进行更新和更改,以遵守应用程序关闭和重新启动的标准。


重启管理器:是一种新的 C 风格 API,从 Windows Vista 和Windows Server 2008。重启管理器由 一个 DLL 组成,应用程序可以加载该 DLL 以访问 Restart Manager API想法 是重启管理器将在安装/更新期间自动神奇地关闭并重启您的应用程序,方法是让应用程序/服务遵循一组准则:

In essence: The whole idea is basically to prefer restarting applications rather than restarting the OS - and also to avoid reboots in general.. To that end: 1) Your application calls RegisterApplicationRestart() with a command line specified for its eventual restart - it "signs up" for restart management. 2) Your application watches for WM_QUERYENDSESSION messages and shuts down gracefully saving data in an appropriate way when told to do so. 3) Then Restart Manager can restart the application when finished installing (restart can be disabled).

更多技术资料:


重启管理器配置:有许多属性会影响重启管理器如何与Windows一起运行安装人员:

Restart Manager is used, the MsiRMFilesInUse dialog is used instead of the FileInUse dialog 显示已锁定文件的应用程序列表时。

N.B! 整个 Restart Manager 功能也可以通过策略禁用:


FileInUse

如果您没有时间或资源来实现与 Restart Manager 的适当互操作性(坦率地说,这是目前 Windows开发),那么有一些事情可能需要知道:

  • Silent Install:首先要指出的是,如果安装,将不会出现 FileInUse 对话框静默模式 中的设置。但是,这可能会触发系统重新启动,除非您指定 REBOOT=ReallySuppress property.
  • Services: 是否安装了 services 升级过程中没有正确关闭?升级期间有 built-in MSI constructsshut down services - Service Control table
    • 如果使用得当,此 ServiceControl 功能意味着您不再遇到任何触发重新启动的服务可执行文件被替换的问题(除非服务本身出现关闭问题)。
    • 这是一个内置的 MSI 结构,如果使用得当,效果很好。人们不应诉诸自定义操作来安装服务。
  • 应用程序支持:除了与 Restart Manager 的互操作性之外,一些正在使用文件的应用程序可以关闭优雅地被告知这样做。
    • 一些应用程序在发送命令行时正常关闭,例如 App.exe -shutdown,尽管没有编写为与 Restart Manager 互操作。也许系统托盘应用程序不为用户保存任何数据?
    • 这显然必须专门为有问题的应用程序实现 - 如果你这样做,此时你应该使用 Restart Manager 代替(或者另外,你可以同时调用相同的实际关闭实施)。
  • “Setup Overkill”:某些设置旨在仅终止安装时打开的应用程序进程。
    • 不理想,但它可以用于后台 运行 的某些类型的应用程序(好吧,这很疯狂,但它是定期完成的)。
    • 使用自定义操作或部署工具中可用的任何内置结构。
  • REINSTALLMODE: 你可能使用REINSTALLMODE="amus"强制覆盖文件在安装过程中?
    • 这会显着增加正在使用的文件数量和重新启动提示,因为 所有 文件都被尝试替换 - 通常是不必要的 - 特别是在 repairmodify场景。
    • 对于安装未正确使用 ServiceControl table 的服务的设置,在尝试覆盖其二进制文件之前关闭服务尤其如此。
  • Side-By-Side Installations (SO): 加入此供参考,超出了“通常相关”的范围。这种方法需要相当多的技术更改和适当的分发流程才能成功——在我看来,它主要用于内部核心企业应用程序(可能有完整的应用程序控制)。
    • 新版本,针对新的安装文件夹(将版本号添加到安装文件夹?),通常可以在没有任何文件覆盖问题的情况下安装(除非更新了任何系统共享文件 - 在这种情况下,您应该将它们拆分到一个单独的先决条件 MSI - 有自己的分发逻辑 - 在需要时 - 应该很少)。
    • 旧版本的卸载仍然会触发重新启动要求,因为文件可能正在使用中,尚未准备好卸载。显然。
    • 您可以为设置组件使用自动 GUID - 这样 MSI 就可以以正确的方式单独跟踪它们。您通常必须消除所有设置静态组件的需要(或者它们必须安装到共享位置并保持静态 - 或者在需要时通过单独的先决条件 MSI 进行更新)。
    • 整个应用程序必须“表现良好”才能并行使用和安装。换句话说,不要争夺文件关联并正确加载所有资源并管理可以在实例之间共享的数据库连接等...
    • 您将版本号添加到开始菜单快捷方式?显然,您必须能够以某种方式区分安装并启动所需的版本。应用程序应该知道它的分身?
    • 我可能会考虑为每个版本设置一个新的升级代码,以便将产品彼此解耦,然后使用分发系统卸载旧的遗留版本(作为周末或每月的批处理作业?)。这不是 100% 必要的,这完全取决于您的情况。如果连贯计划,很多事情都会奏效 - 显然。
    • 不适合正常并行操作的应用程序有时可能会使用 App-V(虚拟包)进行虚拟化和沙盒化,以允许不同版本在同一个盒子。新的挑战。

一些进一步的链接:

  • FileInUse or FilesInUse(来自赛门铁克员工的大量内部信息)
  • Terminating process in CustomAction
  • How can I stop an .exe on repair, update and delete in wix?
  • RmGetList() API fails when file is locked using Ez file locker but works with another file locking utility

假设您是包的作者,我建议您遵循使用 MsiRMFilesInUse 对话框的规范。但是,如果您无论如何都想尝试禁用某些功能,请先了解 Using Windows Installer with Restart Manager:

上包作者的指南
  • Add the MsiRMFilesInUse dialog box to your package. If the MsiRMFilesInUse dialog box is present in the package, the Windows Vista user running an installation at the Full UI user interface level is given the option to automatically close and restart applications. An installation package can contain information for both the MsiRMFilesInUse dialog box and the FilesInUse dialog box. The MsiRMFilesInUse dialog box is only displayed if the package is installed with at least Windows Installer 4.0 on Windows Vista, and is otherwise ignored. Existing packages that do not have the MsiRMFilesInUse dialog box continue to function using the FilesInUse dialog box. A customization transform can be used to add an MsiRMFilesInUse dialog box to existing packages. End-users typically run installations at the Full UI user interface level. Basic UI or Reduced UI level installations give the user the option of using the Restart Manager to reduce system restarts even if the MsiRMFilesInUse dialog box is not present. Silent UI level installations always shut down applications and services, and on Windows Vista, always use Restart Manager.

    : : :

  • Package authors can base a condition in the LaunchCondition table on the MsiSystemRebootPending property to prevent the installation of their package when a system restart is pending.

  • Package authors and administrators can control the interaction of the Windows Installer and Restart Manager by using the MSIRESTARTMANAGERCONTROL, MSIDISABLERMRESTART, MSIRMSHUTDOWN properties and the DisableAutomaticApplicationShutdown policy.

设置<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa370377" rel="nofollow noreferrer">MSIRESTARTMANAGERCONTROL</a>=Disable, possibly removing the FilesInUse and MsiRMFilesInUse dialogs from your package, and optionally tweaking further settings discussed on System Reboots (such as setting the REBOOT or REBOOTPROMPT属性)可能会达到你想要的效果。

如果您不是包的作者,您可能问错了论坛。这 DisableAutomaticApplicationShutdown 策略听起来可以完成您描述的大部分内容,并且适用于您机器上安装的所有软件包。它旨在供系统管理员而不是包作者使用。或者,您可以创建转换(或在安装命令行上指定属性)以有效地改变包,就像包作者所做的那样。

希望不要在这里重复太多,但我会首先指出该对话框的原因是为了避免重新启动。您没有说明为什么要等待重新启动而不是使用使您首先避免重新启动的正在使用的功能。还不清楚你下次重启的时间,问题是应用程序的安装要等到所有文件都被完全替换和更新后才能完成。未完全安装的应用程序崩溃并不罕见,因为它的当前状态是一些新旧文件混合在一起。

  1. 没有MsiRMFilesInUse 属性,所以设置没有效果。

  2. MSIRESTARTMANAGERCONTROL 属性 告诉 Windows 是使用旧的 FilesInUse 行为还是新的 Restart Manager FilesInUse 检测使用中的方法。它不会关闭正在使用的文件行为检测,它只是新旧方法之间的切换。由于检测方法不同,您可能会看到不同的行为,具体取决于实际使用的文件(旧方法仅检测打开 windows 的应用程序)。

  3. 您应该说出您使用哪种工具来构建 MSI 文件,因为它们具有不同的功能。 Visual Studio 安装程序几乎不支持自动关闭,除非您使用安装程序安装服务 类 然后您的卸载方法可以扩展为在卸载时停止服务。如果您使用的是 WiX,则有 util::CloseApplication 功能。

  4. 支持的Windows关机方法是将您的应用程序与Restart Manager集成,Stein有链接。对于服务,使用 MSI ServiceInstall/ServiceControl 安装的 "normal" 服务会解决这个问题,但对于使用安装程序 类.

    [=27= 的 Visual Studio 安装项目则不会]

最后,创建一个 MSI 详细日志并查找正在使用的条目,通常带有 1603 错误(文件正在使用,而不是安装崩溃)。如果对话框告诉您需要关闭的应用程序,您可能不需要此日志,因此只需关注一种让它们在更新时停止的方法,因为这是一个更好的解决方案,而不是试图抑制默认的 Windows 行为.