【问题标题】:How do I use WiX to install PeterKottas.DotNetCore.WindowsService?如何使用 WiX 安装 PeterKottas.DotNetCore.WindowsService?
【发布时间】:2017-08-31 14:56:48
【问题描述】:

我在 DotNet Core 中构建了一个 Windows 服务,该服务与 Peter Kottas WindowsServer nuget (https://github.com/PeterKottas/DotNetCore.WindowsService) 一起安装。为了安装服务,您必须发布代码,将其部署在任何地方,以管理员权限运行 cmd 提示符,将目录移动到部署的代码并执行以下行:“MyService action:install”

<CustomAction Id="CallCmd" Value="[SystemFolder]cmd.exe" Directory="MYSERVICE" />
<CustomAction Id="MoveDirectory" Directory="MYSERVICE" ExeCommand="cd C:\Program Files (x86)\MYCOMPANY\MYSERVICE"/>
<CustomAction Id="CA_InstallMyService" Directory="MYSERVICE" ExeCommand="MyService action:install" />

<InstallExecuteSequence>
  <Custom Action="CallCmd" After="PublishProduct" />
  <Custom Action="MoveDirectory" After="CallCmd" />
  <Custom Action="CA_InstallMyService" After="MoveDirectory" />
</InstallExecuteSequence>

在 Orca 中查看它的顺序似乎是正确的,因为这些说明在创建之前无法浏览到该文件夹​​。

但是,在执行 MSI 并单击“安装”后,它会运行到一半,失败并在安装过程中向后运行。 (我已尝试查看“Program Files (x86)”目录,甚至没有看到我的 Product.wxs 中正在创建的目录文件夹结构。

在事件查看器中稍作挖掘会显示此错误:

错误 1721。此 Windows 安装程序包有问题。一种 无法运行完成此安装所需的程序。 请联系您的支持人员或软件包供应商。行动: MoveDirectory,位置:C:\WINDOWS\SysWOW64\cmd.exe\,命令:cd C:\Program Files (x86)\MYCOMPANY\MYSERVICE

【问题讨论】:

  • 您可以删除 CallCmd 和 MoveDirectory 自定义操作,改为使用 cmd.exe /c "C:\Program Files (x86)\MYCOMPANY\MYSERVICE" action:install
  • 谢谢菲尔,这正是我所需要的,经过一些 cmd 谷歌搜索并将其从安装程序上的最终自定义操作中运行

标签: windows service wix windows-installer


【解决方案1】:

考虑到 Windows Installer(和 WiX)内置支持安装服务以及启动和停止服务以便替换或卸载它们,这不是一个好的设计范例。该 nuget 可能是一个有趣的服务模型,但启动、停止和部署并不是使用 Windows Installer 安装服务的推荐方式。根本不需要运行代码。

请参阅 WiX ServiceInstall 和 ServiceControl 元素。

【讨论】:

  • 请参阅github.com/iswix-llc/iswix-tutorials 获取快速教程,了解如何以正确的方式快速完成。
  • 我同意这是服务的方式,但主要产品是使用 DotNet Core 2 构建的,而服务是使用 Peter Kottas Windows Service git 项目构建的,因此安装服务是不同的到一个普通的 .NetFramework Windows 服务类型项目
  • .Net FW 服务仍然可以通过 Windows Installer 启动和停止以及安装/卸载。托管框架实际上只是普通服务之上的托管代码层。
【解决方案2】:

您必须将您的 CustomAction 标记为 Execute="Deferred"

InstallExecuteSequence 分两部分进行,第一部分是计划阶段,它会确定将要做什么,第二部分是在提升的上下文中运行它刚刚创建的计划脚本。

如果您在 InstallExecuteSequence 中计划了一些自定义操作但未将它们标记为延迟,则它们将在执行序列的计划部分运行,即在安装任何文件之前,因为 InstallFiles 标准操作需要提升并且会发生这种情况当它运行计划的脚本时,在序列的第二部分。

通常,当您需要运行需要安装的属性值的提升自定义操作时,您会使用此模式。您安排了两个自定义操作,一个是延迟的,一个是非延迟的,其中非延迟操作实际上设置了一些特殊值,以供延迟操作在执行时使用。

我之前没有为 CustomActions 使用过 Directory 属性,所以您可能需要重新编写其中的一些操作才能让它们工作,我不确定。

如果您需要更改自定义操作的工作方式,这个其他问题的答案应该有助于解释延迟自定义操作如何在运行时从安装程序的属性中获取值。

WiX - commit more than one Property to deferred Custom Action

【讨论】:

    【解决方案3】:

    虽然我同意 PhilDW 提供的答案,即处理 Windows 服务的最理想方式是使用 WiX 提供的功能,但这里的问题是 DotNetCore 被设计为多平台,目前不包含任何Windows 服务的 .Net 标准程序集,因此我使用 Peter Kottas 的 nuget 包来实现 Windows 服务。解决这个问题的方法可能是使用 docker 容器 - 但是,这超出了当前版本的范围,所以我是如何解决这个问题的:

    TLDR:当用户退出应用程序时,我通过 CustomAction 调用了安装命令。这需要管理权限,因此已在 MSI 中设置了适当的标志,并且始终使用引导程序 (Burn) 应用程序运行 MSI,以便以用户友好的方式授予这些权限。

    首先,我创建了一个自定义操作来在命令提示符中触发安装命令。

    <CustomAction Id="CA_InstallService" Directory="INSTALLDIR" Return="ignore" ExeCommand="cmd /s /c &quot;MyService action:install start-immediately:false&quot;" />
    

    然后我创建了一个新的 WiX UI 元素。它的 WixUI_Mode 是“FeatureTree”,我在退出对话框中添加了一个额外的“DoAction”属性,以便在用户单击 Finish 时调用 customaction。

    <Publish Dialog="ExitDlg" Control="Finish" Event="DoAction" Value="CA_InstallService" Order="990"></Publish>
    

    安装程序需要管理员权限才能调用它,因此在 Product.wxs 文件中将 Package 元素上的“InstallPrivileges”属性设置为“elevated”。现在,如果您通过具有管理员权限的命令提示符调用 msi,这将成功调用“action:install”。 或者您可以创建一个引用您的 wix 安装程序的引导程序项目,并在“MsiPackage”上的 Bundle.wxs 文件中将“ForePerMachine”属性设置为“yes”。

    请参阅 cmets 了解我自己的一些松散相关的旁注。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多