当有文件的更新补丁必须用现有文件替换时,如果其中一个文件正在被任何进程使用,则会弹出一个正在使用的文件对话框。我想避免该对话框并让该文件排队等待安装,以便可以在系统重新启动时安装。我已经读过,在重新启动时排队更新文件是 Windows 安装程序的内置功能。有人可以建议我删除该 FileInUse 对话框的方法。我尝试将“MsiRMFilesInUse”属性设置为“0”,但没有成功。
3 回答
“短”的答案
本质上:您可以完全静默运行(抑制正在使用的文件对话框),正常关闭锁定应用程序(应用程序更新以允许正常关闭 - 有或没有重新启动管理器支持),确保正确的服务控制(如果处理服务),强制杀死正在运行的进程(“大锤方法”),如果检测到锁则中止设置,部署前需要注销,安装到每个版本的新文件夹(并行安装)等...
1)
2)
3)
4)
5)
6)
7)
下面是对文件使用问题和重启管理器的一些深入分析- 旨在快速查看文件使用和重启问题。
就你的实际问题而言。我不会弄乱FileInUse dialog(s)
. 它不会真正解决你的问题。也许考虑这些指针:
- 服务:如果您正在安装服务并且它们触发了文件使用问题,请参阅底部的服务部分以确定您是否可以改进设置的逻辑。
- 静默模式:在静默模式下运行您的设置将是抑制此类文件正在使用对话框的明显方法,但您必须禁止自动重新启动,否则系统将在没有警告的情况下自发重新启动。详情如下。
- 策略:请检查是否在您的盒子/标准 PC 配置上启用了DisableAutomaticApplicationShutdown 策略。请参阅下面的详细信息。
- 注册表位置是:
HKLM\Software\Policies\Microsoft\Windows\Installer
. - 我不确定启用此策略是否会使正在使用的文件对话框消失。
- 注册表位置是:
- 重新启动管理器合规性:也许检查您是否应该更新您的应用程序以注意重新启动管理器功能的设计- 以允许通过应用程序正常关闭自身进行自动魔术和无问题升级(前提是您正在处理您可以实际更改的二进制文件你自己——换句话说:你有源代码)。下面有很多细节。
- "Setup Overkill":如果您认为在升级期间可以安全地杀死您的应用程序,请参阅下面的部分。
- Graceful Shutdown Custom Action:如果您使您的应用程序能够正常关闭(重新启动管理器样式),那么您也可以通过立即模式自定义操作(如果重新启动管理器是被策略禁用 - 但请注意时间和超时问题 - 特别是对于静默运行 - “死锁”)。
- 并排安装:下面的一些细节。一些公司决定真正并行安装应用程序,因此他们的新部署不存在文件覆盖问题(旧版本卸载可能仍会触发所需的重新启动)。
我想如果检测到锁定的文件,您也可以中止安装,或者您可以要求用户在安装运行之前注销- 如果您有分发系统。
请至少浏览其余答案以获取更多详细信息和上下文。
重启管理器
您的应用程序和服务应该准备好被重新启动管理器关闭,并保存干净重新启动所需的用户数据和状态信息。这需要对应用程序/服务进行更新和更改,以遵守关闭和重新启动应用程序的标准。
重启管理器:是一种新的 C 风格 API,从 Windows Vista 和 Windows Server 2008 开始可用。重启管理器由单个 DLL组成,应用程序可以加载该 DLL 以访问重启管理器 API。这个想法是重新启动管理器将在安装/更新期间自动关闭并重新启动您的应用程序,方法是让应用程序/服务遵循一组准则:
本质上:
The whole idea is basically to prefer restarting applications rather than restarting the OS - and also to avoid reboots in general.
。为此:1)
您的应用程序RegisterApplicationRestart()
使用为其最终重新启动指定的命令行调用 - 它“注册”以进行重新启动管理。2)
您的应用程序监视WM_QUERYENDSESSION
消息并在被告知时以适当的方式优雅地关闭保存数据。3)
然后Restart Manager可以在安装完成后重新启动应用程序(可以禁用重新启动)。
更多技术资料:
重新启动管理器配置:有许多属性会影响重新启动管理器将如何与 Windows Installer 一起运行:
- MSIRESTARTMANAGERCONTROL - 使用重新启动管理器或 FileInUse 对话框
- MSIDISABLERMRESTART - 重新启动或不重新启动关闭应用程序
- MSIRMSHUTDOWN - 关机、强制关机或不强制关机
使用Restart Manager时,使用MsiRMFilesInUse对话框而不是FileInUse 对话框来显示已锁定文件的应用程序列表。
注意!整个重启管理器功能也可以通过策略禁用:
- DisableAutomaticApplicationShutdown 策略。
- 入住
HKLM\Software\Policies\Microsoft\Windows\Installer
。 - 使用 Windows 安装程序重新启动管理器行为
文件使用中
如果您没有时间或资源来实现与重新启动管理器的正确互操作性(坦率地说,这是在 Windows 开发的这一点上花费您的资源的唯一理智的事情),那么有一些事情可能是好的知道:
- 静默安装:首先要指出的是,如果您以静默模式
FileInUse
安装设置,则不会出现对话框。但是,除非您指定.REBOOT=ReallySuppress property
- 服务:您是否安装了升级期间未正确关闭的服务?升级期间有
built-in MSI constructs
to服务控制表。shut down services
- 如果使用得当,此 ServiceControl 功能意味着您不再遇到任何服务可执行文件触发重新启动以被替换的问题(除非服务本身出现关闭问题)。
- 这是一个内置的 MSI 结构,如果使用得当,效果很好。人们不应该诉诸自定义操作来安装服务。
- 应用程序支持:除了与重新启动管理器的互操作性之外,某些应用程序(具有正在使用的文件)可以在被告知这样做时正常关闭。
- “Setup Overkill”:一些设置旨在杀死在安装时打开的应用程序进程。
- 不理想,但它可以用于在后台运行的某些类型的应用程序(好吧,这很疯狂,但它会定期完成)。
- 使用自定义操作或部署工具中可用的任何内置结构。
WiX
:在 WIX 中强行杀死 windows 服务。WiX:关闭应用程序。VBScript
:使用 VBScript 关闭应用程序。Advanced Installer
:如何检测或停止一个进程。Installshield
:杀死进程。杀死进程文档。
- REINSTALLMODE:您可能
REINSTALLMODE="amus"
会在安装过程中使用强制覆盖文件吗?- 这会显着增加正在使用的文件数量和重新启动提示,因为尝试替换所有文件 - 通常是不必要的 - 特别是在
repair
和modify
场景中。 - 对于安装服务的设置尤其如此,这些设置在尝试覆盖其二进制文件之前未正确使用ServiceControl 表来关闭服务。
- 这会显着增加正在使用的文件数量和重新启动提示,因为尝试替换所有文件 - 通常是不必要的 - 特别是在
- 并排安装(SO):添加此内容以供参考,它超出了“通常相关”的范围。在我看来,这种方法需要进行相当多的技术更改和适当的分发流程才能成功 - 它主要用于内部的核心企业应用程序(可能完全控制应用程序)。
- 针对新安装文件夹的新版本(将版本号添加到安装文件夹?)通常可以安装而不会出现任何文件覆盖问题(除非更新任何系统共享文件 - 在这种情况下,您应该将它们拆分为单独的先决条件 MSI -具有自己的分发逻辑 - 需要时 - 这应该很少)。
- 旧版本的卸载仍会触发重新启动要求,因为文件可能正在使用且尚未准备好卸载。明显地。
- 您可以为设置组件使用自动 GUID - 因此 MSI 可以以正确的方式单独跟踪它们。您通常必须消除设置静态组件的所有需要(或者必须将它们安装到共享位置并保持静态 - 或在需要时通过单独的先决条件 MSI 进行更新)。
- 整个应用程序必须“表现良好”才能并行使用和安装。换句话说,不要争夺文件关联并正确加载所有资源并管理可以在实例之间共享的数据库连接等......
- 您将版本号添加到开始菜单快捷方式?不知何故,您必须能够区分安装并启动所需的版本 - 显然。应用程序应该知道它的分身吗?
- 我可能会考虑为每个版本设置一个新的升级代码,以便将产品彼此分离,然后使用分发系统卸载旧的旧版本(作为周末或每月的批处理作业?)。这不是 100% 必要的,这完全取决于您的情况。当计划一致时,很多事情都可以奏效——显然。
- 不适合正常并行操作的应用程序有时可能会使用App-V(虚拟包)进行虚拟化和沙盒化,以允许不同版本在同一个机器上共存。新的挑战。
一些进一步的链接:
假设您是包作者,我建议您遵循规范,即使用 MsiRMFilesInUse 对话框。但是,如果您仍然想尝试禁用某些功能,请先了解包作者在Using Windows Installer with Restart Manager上的指南:
将MsiRMFilesInUse对话框添加到您的包中。如果包中存在 MsiRMFilesInUse 对话框,则在完整 UI用户界面级别运行安装的 Windows Vista 用户可以选择自动关闭和重新启动应用程序。安装包可以包含 MsiRMFilesInUse 对话框和FilesInUse的信息对话框。MsiRMFilesInUse 对话框仅在 Windows Vista 上至少使用 Windows Installer 4.0 安装包时才会显示,否则将被忽略。没有 MsiRMFilesInUse 对话框的现有程序包继续使用 FilesInUse 对话框运行。自定义转换可用于将 MsiRMFilesInUse 对话框添加到现有包。最终用户通常在完整 UI用户界面级别运行安装。即使MsiRMFilesInUse对话框不存在,基本 UI 或简化的 UI 级别安装也使用户可以选择使用重新启动管理器来减少系统重新启动。静默 UI 级安装始终关闭应用程序和服务,在 Windows Vista 上,始终使用重新启动管理器。
: : :
包作者可以将LaunchCondition 表中的条件基于MsiSystemRebootPending 属性,以防止在系统重新启动挂起时安装他们的包。
- 包作者和管理员可以通过使用MSIRESTARTMANAGERCONTROL、MSIDISABLERMRESTART、MSIRMSHUTDOWN属性和DisableAutomaticApplicationShutdown策略来控制 Windows Installer 和重新启动管理器的交互。
设置MSIRESTARTMANAGERCONTROL=Disable
,可能从您的包中删除FilesInUse和MsiRMFilesInUse对话框,并且可以选择调整系统重启中讨论的进一步设置(例如设置REBOOT
或REBOOTPROMPT
属性)可能会产生您想要的效果。
如果您不是包作者,您可能在错误的论坛中提问。DisableAutomaticApplicationShutdown策略听起来像是您描述的大部分内容,并且适用于您机器上安装的所有软件包。 它旨在供系统管理员使用,而不是包作者。或者,您可以创建转换(或在安装命令行上指定属性)以像包作者一样有效地更改包。
希望这里不要重复太多,但我将首先指出该对话框的原因是避免重新启动。您没有说明为什么要等待重新启动而不是使用可让您避免重新启动的正在使用的功能。还不清楚您的下一次重新启动时间,问题是应用程序的安装直到所有文件都被完全替换和更新后才完成。安装不完整的应用程序崩溃并不罕见,因为它的当前状态是一些新旧文件混合在一起。
没有 MsiRMFilesInUse 属性,因此设置它没有效果。
MSIRESTARTMANAGERCONTROL 属性告诉 Windows 是使用旧的 FilesInUse 行为还是新的重新启动管理器 FilesInUse 方法来检测使用中的情况。它不会关闭文件使用中的行为检测,它只是新旧方法之间的切换。由于检测方法不同,您可能会看到不同的行为,具体取决于实际使用的文件(旧方法仅检测到打开窗口的应用程序)。
您应该说明您使用哪个工具来构建 MSI 文件,因为它们具有不同的功能。Visual Studio 安装程序几乎不支持自动关闭,除非您使用安装程序类安装服务,那么您的 Uninstall 方法可以扩展为在卸载时停止服务。如果您使用的是 WiX,则有 util::CloseApplication 功能。
支持的 Windows 关闭方法是将您的应用程序与 Restart Manager 集成,Stein 有链接。对于服务,使用 MSI ServiceInstall/ServiceControl 进行的“正常”服务安装会处理此问题,但对于带有安装程序类的 Visual Studio 安装项目则不然。
最后,创建一个 MSI 详细日志并查找正在使用的条目,通常带有 1603 错误(使用中的文件类型,而不是安装崩溃的类型)。如果对话框告诉您需要关闭的应用程序,您可能不需要此日志,因此只需专注于让它们在更新时停止的方法,因为这是一个更好的解决方案,而不是试图抑制默认的 Windows 行为。