草庐IT

windows - Wix:升级时有时会卸载Windows Service

coder 2024-06-14 原文

我们使用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

如您所见,失败升级的操作为“不存在”,成功升级的操作为“FileAbsent”。从我读过的文件中,FileAbsent意味着该功能已重新安装,而Absent则意味着该功能将被删除。

我的问题是如何确定组件的操作,以及为什么在一台计算机上不存在而另一台文件上却存在FileA。有办法解决这个问题吗?

组件如果配置如下:
  <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)似乎不符合您的意图。您只希望组件在重大升级时不卸载,在这种情况下,通常要做的是将RemoveExistingProducts移到InstallExecuteSequence的后面,这要求您遵循所有组件规则。这是非常复杂的运行时行为,但是是一个简单的概念。本质上,您的新版本将作为补丁程序安装-覆盖文件而无需先卸载它们-由于从未卸载托管服务的组件,因此可以保留您的服务凭据。

早期REP :出于记录,进行重大升级的常用方法是在RemoveExistingProducts的早期安排InstallExecuteSequence,这意味着所有文件都已卸载,然后重新安装。之所以使用这种方法,是因为它允许草率的组件引用。以清除用户数据(例如许可证 key ,服务凭证等)而闻名。

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

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

仅适用于MSI的服务:您也可以将服务安装置于其自己的MSI中,以使其更新对您而言可控-或在无法进行主要设置以遵守组件规则的情况下。在我看来,这也有些复杂,但比自定义操作要好。

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

(托管)服务帐户:您可以使用没有(about service accounts)凭据的常规服务帐户来运行服务-诸如LocalServiceLocalSystemNetworkService(显然,我想这对您来说是不可能的)。或者是managed service accountsgroup managed service accounts或虚拟帐户step-by-step info的较新概念(我不太了解的概念)。

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

现实世界中常见的MSI问题:我写了一些有关MSI实际应用中常见的常见问题,前文提到:How do I avoid common design flaws in my WiX / MSI deployment solution?不好。我对它不是很满意-它缺少一种以上的方式-但如果有帮助,它确实存在。在可用的时间里,这是最大的努力。请理解它的含义:现实问题的未完成转储,这里和那里有一些指针,您可以尝试解决该问题。

链接:

  • Chris Painter on service credential preservation
  • 关于windows - Wix:升级时有时会卸载Windows Service,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50364741/

    有关windows - Wix:升级时有时会卸载Windows Service的更多相关文章

    1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

      我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

    2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

      尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

    3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

      我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

    4. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

      我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

    5. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

      这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

    6. ruby - 在不使用 RVM 的情况下在 Mac 上卸载和升级 Ruby - 2

      我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案

    7. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

      之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

    8. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

      深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

    9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

      我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

    10. ruby - 如何在 Ruby 中执行 Windows CLI 命令? - 2

      我在目录“C:\DocumentsandSettings\test.exe”中有一个文件,但是当我用单引号编写命令时`C:\DocumentsandSettings\test.exe(我无法在此框中显示),用于在Ruby中执行命令,我无法这样做,我收到的错误是找不到文件或目录。我尝试用“//”和“\”替换“\”,但似乎没有任何效果。我也使用过系统、IO.popen和exec命令,但所有的努力都是徒劳的。exec命令还使程序退出,这是我不想发生的。提前致谢。 最佳答案 反引号环境就像双引号,所以反斜杠用于转义。此外,Ruby会将空格解

    随机推荐