【问题标题】:Installing a multi-file NT Service using WiX (2.0)使用 WiX (2.0) 安装多文件 NT 服务
【发布时间】:2009-08-12 13:55:49
【问题描述】:

如何在 WiX 中安装带有一些附加文件的服务,并定义什么文件是实际的服务 EXE 文件?

场景:我有一个服务,它只是一个 EXE 文件,并使用以下代码将其安装为 WiX 中的 Windows NT 服务:

<Component Id='InstallMyServiceComponent' Guid='{....}' DiskId='1'>
   <File Id='InstallMyServiceEXEFile' LongName='MyService.exe' 
         Name='MyServ.exe' src='MyService/bin/release/MyService.exe' KeyPath='yes'/>
   <ServiceInstall Id='InstallMyService' Name='MyService' Description='My Service'
         ErrorControl='normal' Start='auto' Type='ownProcess' Vital='yes' />
   <ServiceControl Id='UninstallMyService' Name='MyService' Remove='uninstall' 
         Wait='yes' />
</Component>
<Component Id='RunMyServiceComponent' Guid='.......'>
   <ServiceControl Id='RunMyService' Name='MyService' Start='install' 
         Stop='uninstall' Wait='no' />
</Component>

我有一个功能可以安装和选择启动这个服务。

现在,我的问题是 - 现在我的服务已经增长,单个 EXE 不再是单个 EXE - 它是多个文件、EXE、DLL 和一些支持文件。

但是,我现在该如何安装呢??

我试图让一个包含我所有文件的组件

<Component Id="MyService" Guid="......" DiskId="1">
  <File Id="fileMyService_framework_dll" LongName="Framework.dll" 
        Name="Framewrk.DLL" src="MyService\Framework.dll" />
  <File Id="fileMyService_dal_dll" LongName="MyServiceDAL.dll" 
        Name="SrvcDAL.DLL" src="MyService\ServiceDAL.dll" />
  <File Id="fileMyService_helpers_dll" LongName="Helpers.dll" 
        Name="Helpers.DLL" src="MyService\Helpers.dll" />
  <File Id="fileMyService_exe" LongName="MyService.exe" 
        Name="MySrv.EXE" src="MyService\MyService.exe" />
</Component>

首先,我尝试将 ServiceInstall 和 ServiceControl 标签添加到该组件中:

<Component Id="MyService" Guid="......" DiskId="1">
  <File Id="fileMyService_framework_dll" LongName="Framework.dll" 
        Name="Framewrk.DLL" src="MyService\Framework.dll" />
  <File Id="fileMyService_dal_dll" LongName="MyServiceDAL.dll" 
        Name="SrvcDAL.DLL" src="MyService\ServiceDAL.dll" />
  <File Id="fileMyService_helpers_dll" LongName="Helpers.dll" 
        Name="Helpers.DLL" src="MyService\Helpers.dll" />
  <File Id="fileMyService_exe" LongName="MyService.exe" 
        Name="MySrv.EXE" src="MyService\MyService.exe" />
   <ServiceInstall Id='InstallMyService' Name='MyService' 
        Description='My Service' ErrorControl='normal' Start='auto' 
        Type='ownProcess' Vital='yes' />
   <ServiceControl Id='UninstallMyService' Name='MyService' 
        Remove='uninstall' Wait='yes' />
</Component>

然后我的“Framework.dll”被设置为正在创建的服务的源路径............

所以我想我会创建第二个组件来实际安装服务,使用 ServiceInstall,我只是使用 FileRef 引用该服务 EXE 文件 - 但这似乎不存在(至少在 Wix2 中)。

<Component Id='InstallMyServiceComponent' Guid='{....}' DiskId='1'>
   <FileRef Id='fileMyService_exe' KeyPath='yes'/>
   <ServiceInstall Id='InstallMyService' Name='MyService' 
         Description='My Service' ErrorControl='normal' Start='auto' 
         Type='ownProcess' Vital='yes' />
   <ServiceControl Id='UninstallMyService' Name='MyService' 
         Remove='uninstall' Wait='yes' />
</Component>

那么 - 一个可怜的 WiX 作者必须做些什么来安装所有必要的文件,并且仍然让 NT 服务安装来选择正确的 EXE 文件(不仅仅是组件文件列表中的任意文件)??

马克

【问题讨论】:

  • 您忘记在文件元素中的 exe 上设置 KeyPath='yes'。
  • 谢谢,Shay - Rob 的回答似乎证实了您的说法 - 非常感谢!

标签: windows-services wix wix2


【解决方案1】:

ServiceInstall 元素最终将指向 ServiceInstall 所在组件的“KeyPath”。默认情况下,WiX 工具集选择组件中的第一个 File 或 RegistryKey 元素作为 KeyPath。当您将文件添加到组件时,列表顶部的 .dll 成为 KeyPath。

一般来说,较小的组件比较大的组件要好。因此,更好的解决方案是将您的 DLL 放在单独的组件中。然后,您可以将 .exe 文件元素和 ServiceInstall 元素保留在同一个组件中。这使得一切都非常干净。

如果您希望将“服务”组合在一起,您可以创建一个 ComponentGroup 元素并将 ComponentRefs 放入 .exe 和 .dll 组件。现在你有了一个可以从 Feature/ComponentGroupRef 引用的东西。

【讨论】:

  • +1 很好的解释 - 非常感谢,Rob!我相应地更改了我的 WiX 脚本,一旦运行夜间构建并且安装已经过测试,我会在明天报告:-)
  • 是的,确认 - 添加“KeyPath='yes'”解决了我的问题 - 安装恢复正常 - 非常感谢,Rob!
猜你喜欢
  • 2012-11-05
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多