加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Wix:升级时有时会卸载Windows服务

发布时间:2020-12-14 05:57:36 所属栏目:Windows 来源:网络整理
导读:我们用Wix安装我们的软件.我们的设置还安装了 Windows服务.要允许用户更改Windows服务的登录信息,我们只想在首次安装时安装该服务,并仅在卸载时将其删除.对于升级,我们手动停止服务,以便可以升级文件. 我们有这个工作,但最近我们发现在某些机器上,在Unpublis
我们用Wix安装我们的软件.我们的设置还安装了 Windows服务.要允许用户更改Windows服务的登录信息,我们只想在首次安装时安装该服务,并仅在卸载时将其删除.对于升级,我们手动停止服务,以便可以升级文件.

我们有这个工作,但最近我们发现在某些机器上,在UnpublishFeatures期间卸载了Windows服务:

如果失败的升级日志:

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: UNKNOWNInstallerFeatures84B659030632F794E93A7CB19A87DB8E 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,ByteEquivalent=1300000)
MSI (s) (D8:EC) [13:41:38:393]: Executing op: ServiceControl(,Action=8,)
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,Component=
UnpublishFeatures: Feature: Main
MSI (s) (CC:3C) [11:53:24:977]: Note: 1: 1402 2: UNKNOWNInstallerFeatures84B659030632F794E93A7CB19A87DB8E 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:WindowsInstallerMSI170B.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

正如您所看到的,升级失败的操作是“缺席”,而成功升级的操作是FileAbsent.据我所知,FileAbsent意味着重新安装了该功能,而Absent意味着该功能将被删除.

我的问题是如何确定组件的操作,以及为什么它在一台机器上缺席并在另一台机器上FileAbsent.有没有办法解决这个问题?

组件如果配置如下:

<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>

解决方法

空白组件GUID:Guid =“”这是您最近设置的内容吗?我相信,这将为组件设置一个空白的GUID,这意味着它将在第一次安装时安装,之后从未接触或升级(除非您在升级时找到了重新安装组件的技巧) – 并且它不会据我记得,已卸载.

晚REP:以上(空白GUID)似乎不是你想要的.您只是希望组件在主要升级时不卸载,在这种情况下,您通常会在InstallExecuteSequence中移动RemoveExistingProducts – 这需要您遵循所有组件规则到字母.这是非常复杂的运行时行为,但是一个简单的概念.基本上,您的新版本将作为补丁安装 – 覆盖文件而不先卸载它们 – 允许保留您的服务凭据,因为从不卸载托管服务的组件.

早期REP:只是为了记录,进行主要升级的常用方法是在InstallExecuteSequence的早期安排RemoveExistingProducts,这意味着卸载所有文件,然后重新安装.使用此方法是因为它允许草率组件引用.它用于清除许可证密钥,服务凭证等用户数据…

永久组件:另一种方法是将托管组件设置为永久性.然后它将永远不会在主要升级期间卸载(即使您使用早期REP),但也不会在常规卸载期间卸载,因此在系统上搁置有问题的文件(除非您添加自己的自定义清理功能 – 这可能非常容易出错).

自定义操作备份机制:其他人依靠自己的自定义操作(example)来备份在升级期间被清除的数据,然后在升级完成后重新应用它们.在我看来,这是一种非常容易出错的方法.

仅限服务MSI:您还可以将服务安装放在其自己的MSI中,以使其更新更易于控制 – 或者在主要设置无法满足组件规则的情况下.这也有点复杂,但比我视图中的自定义操作要好.

次要升级:如果您可以使用次要升级来安装升级,则可以避免此服务凭据问题.我将链接到另一个描述这个问题的答案:Restarting windows service during WIX upgrade.

(托管)服务帐户:您可以使用没有(about service accounts)凭据的常规服务帐户来运行服务 – 例如LocalService,LocalSystem或NetworkService(显然这对我来说是不可能的).或managed service accounts,group managed service accounts或虚拟账户step-by-step info的新概念(我不太了解的概念).

其他方法:毫无疑问,其他方法也是如此.我想您可以将服务配置保留在MSI之外并通过脚本应用它.我不推荐它.我知道有些人在使用服务和计划任务之间切换,具体取决于the nature of the task at hand(如果是task that runs only once in a while,则基本上切换到计划任务).虽然有风险,但我认为您可以将服务配置推迟到用户在安装后启动的高级EXE(显然用户必须是管理员),然后可以设置具有一定交互性的配置(错误和状态消息直接到用户 – 而不仅仅是隐藏在日志中)有时可以帮助人们前进.虽然不是我推荐的方法 – 提升动作是设置的目的.我喜欢在应用程序中执行的任何非提升配置.

常见的真实MSI问题:我曾经写过一些在MSI的实际应用中看到的常见问题,这里是:How do I avoid common design flaws in my WiX / MSI deployment solution?这不是很好.我对此并不是很满意 – 它缺乏多种方式 – 但它确实存在,以防它可以提供帮助.在可用的时间内尽力而为.请把它当作它的原因:一个未完成的实际问题转储,在这里和那里有几个指针,你可以尝试解决这个问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读