如何在Wix Burn安装完成后保存安装程序EXE文件
解决Wix Burn安装后保存原EXE的权限问题
针对你遇到的核心服务器需要保留Burn安装程序副本的场景,我整理了几个可行的解决方案,绕开权限限制的同时满足需求:
方案1:让整个Burn Bundle以管理员身份运行
既然ApplyComplete阶段的权限问题源于Burn未获取管理员权限,最简单的办法是强制Bundle启动时请求管理员权限,这样后续所有阶段(包括ApplyComplete)都拥有足够权限执行文件复制。
具体实现:在你的Bundle项目中,给<Bundle>元素添加ElevationRequired="yes"属性,确保启动时触发UAC弹窗获取权限:
<Bundle Name="YourApp" Version="1.0.0.0" Manufacturer="YourCompany" ElevationRequired="yes"> <!-- 其他Bundle配置 --> </Bundle>
然后在ApplyComplete阶段添加自定义动作,利用WixBundleOriginalSource变量复制原EXE到目标路径:
<CustomAction Id="SaveBundleExe" Execute="commit" Impersonate="no" Directory="TARGETDIR" ExeCommand="cmd.exe /c copy "[WixBundleOriginalSource]" "C:\YourCoreServerBackup\YourBundle.exe"" /> <InstallExecuteSequence> <Custom Action="SaveBundleExe" After="InstallFinalize">NOT REMOVE</Custom> </InstallExecuteSequence>
优点:配置简单,无需额外开发;缺点:强制整个安装流程都需要管理员权限,可能不符合普通服务器的轻量安装场景。
方案2:用独立的权限提升工具执行复制
如果不想让整个安装都触发UAC,可以编写一个小型控制台工具,专门负责文件复制,且这个工具的manifest设置为requireAdministrator。让Burn在安装完成后调用这个工具,仅在复制环节请求权限。
步骤如下:
- 编写复制工具:比如用C#写一个控制台程序,接收两个命令行参数(原EXE路径、目标保存路径),执行文件复制逻辑,同时在项目属性中设置“嵌入的资源清单”为“要求管理员权限”。
- 将工具打包到Bundle的Payload中:
<Payload SourceFile="BundleCopyTool.exe" />
- 在ApplyComplete阶段调用工具:
<CustomAction Id="RunCopyTool" Execute="immediate" Directory="WixBundlePayloadFolder" ExeCommand="BundleCopyTool.exe "[WixBundleOriginalSource]" "C:\YourCoreServerBackup\YourBundle.exe"" /> <InstallUISequence> <Custom Action="RunCopyTool" After="ApplyComplete">NOT REMOVE AND Installed</Custom> </InstallUISequence>
优点:仅复制操作需要权限,安装流程其余部分可以保持非管理员权限;缺点:需要额外开发和维护一个小工具。
方案3:借助MSI的管理员权限完成复制
虽然MSI不能部署原Burn EXE,但可以让MSI接收Burn传递的原EXE路径,利用MSI运行时的管理员权限完成复制——这也符合WiX“大部分操作放在MSI中”的最佳实践。
具体步骤:
- 在Bundle中向MSI传递
WixBundleOriginalSource变量:
<MsiPackage SourceFile="YourApp.msi"> <MsiProperty Name="ORIGINAL_BUNDLE_PATH" Value="[WixBundleOriginalSource]" /> </MsiPackage>
- 在MSI项目中添加复制逻辑:
- 先定义核心服务器的保存目录:
<Directory Id="TARGETDIR" Name="SourceDir"> <Directory Id="ProgramFilesFolder"> <Directory Id="INSTALLFOLDER" Name="YourApp" /> </Directory> <Directory Id="BUNDLE_BACKUP_DIR" Name="BundleBackups" Path="C:\YourCoreServerBackup" /> </Directory>- 添加复制组件,仅在核心服务器场景下执行:
<Component Id="SaveBundleComponent" Guid="YOUR-UNIQUE-GUID-HERE" Directory="BUNDLE_BACKUP_DIR"> <CopyFile Id="CopyBundleExe" SourceProperty="ORIGINAL_BUNDLE_PATH" DestinationName="YourBundle.exe" /> <Condition>INSTALL_ROLE="CoreServer"</Condition> <!-- 自定义条件,仅核心服务器安装时触发 --> </Component>- 将该组件关联到核心服务器专属的功能模块中。
优点:遵循WiX设计规范,权限问题由MSI的管理员上下文自动处理;缺点:需要在MSI中添加额外配置,且要区分核心服务器与普通服务器的安装场景。
额外注意事项
WixBundleOriginalSource可能指向网络路径,复制前要确保目标路径是本地路径,或者添加网络文件的下载/复制逻辑;- 复制前可添加判断逻辑,避免覆盖已存在的备份文件(比如给备份文件加上版本号后缀);
- 测试时要验证全新安装、升级、卸载等场景下的复制行为,确保只有安装成功后才执行备份。
内容的提问来源于stack exchange,提问作者Steve0212
相关产品推荐
相关产品推荐

