我们有一个wix项目。它安装了两个Windows服务和一个Windows桌面应用程序,它将显示在任务栏托盘图标中。这两项服务的目的是相互监视和桌面应用程序,以便在任何一项服务未运行时,其他服务将启动它。如果桌面应用程序未运行,则两个服务之一将启动桌面应用程序。
我们希望在安装程序中实现回滚功能,以便在升级到最新版本期间出现任何错误时,安装程序将回滚到以前的现有版本。我们正在使用WixFailWhenDeferred测试回滚。
<CustomActionRef Id="WixFailWhenDeferred" />
回滚似乎与测试一样,安装回滚到以前的版本。例如,在机器中已经安装了v8.0.1.0,当我们运行以下命令时,它会尝试安装v8.0.2.0但最终回滚到8.0.1.0。
>msiexec.exe /passive /norestart /i "D:\setup8.0.2.0.msi" /L*vx+ "d:\test\Installlog8.0.2.0.log" WIXFAILWHENDEFERRED=1
wix代码
<MajorUpgrade Schedule="afterInstallInitialize" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
自定义操作
<CustomAction Id="CertificateInstallCustomAction"
BinaryKey="CertificateCustomActions.CA.dll"
DllEntry="InstallClientCertificate"
Execute="deferred"
Return="check"
Impersonate="no" />
<CustomAction Id="CertificateRemoveCustomAction"
BinaryKey="CertificateCustomActions.CA.dll"
DllEntry="UninstallClientCertificate"
Execute="deferred"
Return="check"
Impersonate="no"/>
<CustomAction Id="ClientInstallCustomAction"
BinaryKey="ClientCustomActions.CA.dll"
DllEntry="InstallValidation"
Execute="deferred"
Return="check"
Impersonate="no"/>
<CustomAction Id="ClientInstallCustomActionRoll"
BinaryKey="ClientCustomActions.CA.dll"
DllEntry="InstallValidation"
Execute="rollback"
Return="ignore" />
<CustomAction Id="ClientRemoveCustomAction"
BinaryKey="ClientCustomActions.CA.dll"
DllEntry="UninstallValidation"
Execute="immediate"
Return="check"/>
<CustomAction Id="StartServiceIfNotRunningIdRoll"
BinaryKey="ClientCustomActions.CA.dll"
DllEntry="StartServiceIfNotRunning"
Execute="rollback"
Return="ignore" />
ClientRemoveCustomAction:此自定义操作是在卸载之前终止桌面应用程序。
序列
<CustomAction Id='AlreadyInstalled' Error='You are running the same version of [ProductName] as you are trying to install.' />
<CustomActionRef Id="WixFailWhenDeferred" />
<InstallExecuteSequence>
<!--<RemoveExistingProducts After="InstallInitialize" />-->
<Custom Action='AlreadyInstalled' After='FindRelatedProducts'>SAME_VERSION_INSTALLED</Custom>
<Custom Action="CertificateInstallCustomAction" After="InstallServices">
(NOT Installed) AND (NOT UPGRADINGPRODUCTCODE) <!-- For install -->
</Custom>
<Custom Action="CertificateRemoveCustomAction" After="CertificateInstallCustomAction">
(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") <!-- For Unintall-->
</Custom>
<Custom Action="ClientInstallCustomAction" Before="CertificateInstallCustomAction" >
(NOT Installed) AND (NOT UPGRADINGPRODUCTCODE) OR (NOT Installed)<!-- For install-->
</Custom>
<Custom Action="ClientInstallCustomActionRoll" Before="ClientInstallCustomAction" >
(Installed OR NOT Installed)
</Custom>
<Custom Action='ClientRemoveCustomAction' Before='InstallValidate'>
(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") OR (REMOVE) <!-- For Unintall and Upgrade, we need to ask the uninstall password-->
</Custom>
<Custom Action='StartServiceIfNotRunningIdRoll' After='InstallInitialize'>
(Installed) <!--This is only for restart the service in case of Rollback.-->
</Custom>
</InstallExecuteSequence>
服务
<ComponentGroup Id="ClientServices" Directory="INSTALLFOLDER">
<Component Id="ABCWD.exe" Guid="*">
<File Id="ABCWD.exe" KeyPath="yes" Source="$(var.ClientSourceDirectory)\ABCWD.exe" />
<wix:ServiceInstall Id="ABCWDServiceInstaller" Type="ownProcess" Name="Service1" DisplayName="Service1"
Description="Enforces enterprise instant messaging policy." Start="auto" ErrorControl="normal" Interactive="no" Vital="yes" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<wix:ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" OnUninstall="no"/>
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" ResetPeriodInDays="1" />
</wix:ServiceInstall>
<wix:ServiceControl Id="ABCWDStartService" Start="install" Stop="both" Remove="uninstall" Name="ABCWD" Wait="yes" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" />
</Component>
<Component Id="SysABCMon.exe" Guid="*">
<File Id="SysABCMon.exe" KeyPath="yes" Source="$(var.ClientSourceDirectory)\SysABCMon.exe" />
<wix:ServiceInstall Id="SysABCMonServiceInstaller" Type="ownProcess" Name="Service2" DisplayName="Service2"
Description="Enforces enterprise instant messaging policy." Start="auto" ErrorControl="normal" Interactive="no" Vital="yes" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<wix:ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" OnUninstall="no"/>
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" ResetPeriodInDays="1" />
</wix:ServiceInstall>
<wix:ServiceControl Id="SysABCMonStartService" Start="install" Stop="both" Remove="uninstall" Name="SysABCMon" Wait="yes" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" />
</Component>
</ComponentGroup>
答案 0 :(得分:0)
实际上,经过一些打击和试验后得到了一个解决方案。为了防止使用File(或阻止关闭应用程序提示),我们必须为CA ClientRemoveCustomAction添加条件REMOVE - 它只会杀死桌面应用程序。
<Custom Action='ClientRemoveCustomAction' Before='InstallValidate'>
(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") OR (REMOVE) <!-- For Unintall and Upgrade, we need to ask the uninstall password-->
</Custom>
当回滚完成后,服务未启动,因此我们必须添加以下自定义操作以在回滚时启动服务。 我们需要了解CA应该尽早排序,以便最后在回滚时执行。
<Custom Action='StartServiceIfNotRunningIdRoll' After='InstallInitialize'>
(Installed) <!--This is only for restart the service in case of Rollback.-->
</Custom>
如果有更好的解决方案,请告诉我。