我们使用 Wix 安装我们的软件。我们的设置还安装了 Windows 服务。为了允许用户更改 Windows 服务的登录信息,我们只想在首次安装时安装该服务,并仅在卸载时将其删除。对于升级,我们手动停止服务,以便可以升级文件。
我们已经做到了这一点,但最近我们发现在某些计算机上,Windows 服务在 UnpublishFeatures 期间被卸载:
如果来自失败的升级日志:
Action 13:41:38: UnpublishFeatures. Unpublishing Product Features
MSI (s) (D8:EC) [13:41:38:346]: Executing op: FeatureUnpublish(Feature=Main,,Absent=2,Component=
UnpublishFeatures: Feature: Main
MSI (s) (D8:EC) [13:41:38:346]: Note: 1: 1402 2: UNKNOWN\Installer\Features\84B659030632F794E93A7CB19A87DB8E 3: 2
MSI (s) (D8:EC) [13:41:38:346]: Executing op: ActionStart(Name=StopServices,Description=Stopping services,Template=Service: [1])
Action 13:41:38: StopServices. Stopping services
MSI (s) (D8:EC) [13:41:38:362]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (D8:EC) [13:41:38:362]: Executing op: ServiceControl(,Name=RidderIQWebApi,Action=2,Wait=1,)
StopServices: Service: Ridder iQ Web API
MSI (s) (D8:EC) [13:41:38:393]: Executing op: ActionStart(Name=DeleteServices,Description=Deleting services,Template=Service: [1])
Action 13:41:38: DeleteServices. Deleting services
MSI (s) (D8:EC) [13:41:38:393]: Executing op: ProgressTotal(Total=1,Type=1,ByteEquivalent=1300000)
MSI (s) (D8:EC) [13:41:38:393]: Executing op: ServiceControl(,Name=RidderIQWebApi,Action=8,Wait=1,)
DeleteServices: Service: Ridder iQ Web API
这是来自成功升级的日志:
Action 11:53:24: UnpublishFeatures. Unpublishing Product Features
MSI (s) (CC:3C) [11:53:24:976]: Executing op: FeatureUnpublish(Feature=Main,,Absent=2,Component=
UnpublishFeatures: Feature: Main
MSI (s) (CC:3C) [11:53:24:977]: Note: 1: 1402 2: UNKNOWN\Installer\Features\84B659030632F794E93A7CB19A87DB8E 3: 2
MSI (s) (CC:3C) [11:53:24:978]: Executing op: ActionStart(Name=RemoveFiles,Description=Removing files,Template=File: [1], Directory: [9])
Action 11:53:24: RemoveFiles. Removing files
如您所见,Windows Installer 会跳过 StopServices/DeleteServices 操作并开始删除文件。由于该服务在安装过程中稍后在 UnpublishFeatures 上被删除,因此它尝试配置该服务,但由于不再安装而失败:
MSI (s) (D8:68) [13:42:34:772]: Executing op: CustomActionSchedule(Action=ExecServiceConfig,ActionType=3073,Source=BinaryData,Target=ExecServiceConfig,CustomActionData=)
MSI (s) (D8:90) [13:42:34:772]: Invoking remote custom action. DLL: C:\Windows\Installer\MSI170B.tmp, Entrypoint: ExecServiceConfig
ExecServiceConfig: Error 0x80070424: Service 'RidderIQWebApi' does not exist on this system.
ExecServiceConfig: Error 0x80070424: Failed to get service: RidderIQWebApi
CustomAction ExecServiceConfig returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 13:42:35: InstallFinalize. Return value 3.
我的猜测是,发生这种情况是因为两次升级的组件操作不同,对于失败的升级,这些是组件操作:
MSI (s) (D8:68) [13:41:26:400]: Component: cmp.SR.SDKWebAPI.Service.exe; Installed: Absent; Request: Local; Action: Local
MSI (s) (D8:EC) [13:41:36:400]: Component: cmp.SR.SDKWebAPI.Service.exe; Installed: Local; Request: Absent; Action: Absent
为了成功升级,组件操作如下:
MSI (s) (CC:44) [11:53:17:386]: Component: cmp.SR.SDKWebAPI.Service.exe; Installed: Absent; Request: Local; Action: Local
MSI (s) (CC:3C) [11:53:22:850]: Component: cmp.SR.SDKWebAPI.Service.exe; Installed: Local; Request: Absent; Action: FileAbsent
如您所见,升级失败的操作为 Absent,升级成功的操作为 FileAbsent。据我所知,FileAbsent 意味着该功能已重新安装,而 Absent 意味着该功能将被删除。
我的问题是如何确定组件的操作,以及为什么它在一台机器上不存在而在另一台机器上文件不存在。有办法解决这个问题吗?
该组件如果配置如下:
<Component Id="cmp.SR.SDKWebAPI.Service.exe" Guid="">
<File Id="fil.SDKWebAPI.Service.exe" Source="SDKWebAPI.Service.exe" KeyPath="yes" />
<File Id="fil.SDKWebAPI.Service.exe.config" Source="SDKWebAPI.Service.exe.config" KeyPath="no" />
<ServiceInstall Id="SDKWebAPI.Service.exe.Installer"
Type="ownProcess"
Name="RidderIQWebApi"
DisplayName="Ridder iQ Web API"
Description="Ridder iQ Web API service"
Start="auto"
Account="LocalSystem"
ErrorControl="ignore">
<util:ServiceConfig FirstFailureActionType="restart"
SecondFailureActionType="restart"
ThirdFailureActionType="restart"
RestartServiceDelayInSeconds="60"
ResetPeriodInDays="0" />
</ServiceInstall>
</Component>