Installation Wix-如何使用一个可执行文件安装多个windows服务?
我正在尝试使用相同的可执行文件安装多个windows服务,但是WiX不喜欢两个文件标记中的相同名称属性。我尝试更改两个文件标记的名称。它可以工作,但我希望我不必为了这个目的安装两个相同的可执行文件。有更好的方法吗?以下是我目前的代码:Installation Wix-如何使用一个可执行文件安装多个windows服务?,installation,wix,Installation,Wix,我正在尝试使用相同的可执行文件安装多个windows服务,但是WiX不喜欢两个文件标记中的相同名称属性。我尝试更改两个文件标记的名称。它可以工作,但我希望我不必为了这个目的安装两个相同的可执行文件。有更好的方法吗?以下是我目前的代码: <Component Id="Service1" Guid="{SOMEGUID1}"> <File Id='Service1' Name='ConnDriver.exe' DiskId='1' Source='..\Service\obj\
<Component Id="Service1" Guid="{SOMEGUID1}">
<File Id='Service1' Name='ConnDriver.exe' DiskId='1' Source='..\Service\obj\x86\$(var.BUILD)\ConnDriver.exe' KeyPath='yes'/>
<ServiceInstall
Id="ServiceInstaller1"
Type="ownProcess"
Name="MyService1"
DisplayName="MyService1"
Description="Some Description"
Start="auto"
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]"
ErrorControl="normal"
Arguments=' "Service1"'
Vital="yes"
Interactive="no" />
<ServiceControl Id="ServiceControl1" Stop="uninstall" Remove="uninstall" Name="MyService1" Wait="yes" />
</Component>
<Component Id="Service2" Guid="{SOMEGUID2}">
<File Id='Service2' Name='ConnDriver.exe' DiskId='1' Source='..\Service\obj\x86\$(var.BUILD)\ConnDriver.exe' KeyPath='yes'/>
<ServiceInstall
Id="ServiceInstaller2"
Type="ownProcess"
Name="MyService2"
DisplayName="MyService2"
Description="Some Description"
Start="auto"
Account="[SERVICEACCOUNT]"
Password="[SERVICEPASSWORD]"
ErrorControl="normal"
Arguments=' "Service2"'
Vital="yes"
Interactive="no" />
<ServiceControl Id="ServiceControl2" Stop="uninstall" Remove="uninstall" Name="MyService2" Wait="yes" />
</Component>
在功能方面:
<Feature Id="Feature1" Title="Feature 2" Level="1" Description="...">
<ComponentRef Id="Service1_xml"/>
<ComponentRef Id="Service1"/>
</Feature>
<Feature Id="Feature2" Title="Feature 2" Level="1" Description="...">
<ComponentRef Id="Service2_xml"/>
<ComponentRef Id="Service2"/>
</Feature>
感谢您的帮助
(顺便说一句,我将它们分成两个组件的原因是,我可以在features部分的服务中包含一个xml配置文件。我的windows service installer接受一个命令行参数,以知道从哪个xml文件读取并相应地配置)
编辑:
错误输出:
ICE30:目标文件“hlo8twix.exe | ConnDriver.exe”由LFN系统上的两个不同组件安装在“[ProgramFilesFolder]\CompanyName\ProgramName\”中:“Service1”和“Service2”。这将中断组件引用计数。一个组件可以属于多个功能。为您的服务创建一个组件,然后创建多个功能:每个功能都有一个
ComponentRef
,指向一个服务组件和它需要的任何其他引用。在我的一个项目中,我在一个可执行文件中有两个服务。因此,对于我的exe中的两个服务,我的wix设置中都有以下内容。希望这有帮助
<Component Id="MyScheduler" Guid="{SOMEGUID}">
<File Id="MySchedulerEXE" Name="MyScheduler.exe" Source="MyScheduler.exe" KeyPath="yes" />
<ServiceInstall Id="FirstService" Type="ownProcess" Vital="yes" Name="First Service" DisplayName="First Service" Description="First Service" Start="auto" Account="NT AUTHORITY\LocalService" Interactive="no" ErrorControl="ignore" />
<ServiceControl Id="StartFirstService" Name="First Service" Start="install" Wait="no" />
<ServiceControl Id="StopFirstService" Name="First Service" Stop="both" Wait="yes" Remove="uninstall" />
<ServiceInstall Id="SecondService" Type="ownProcess" Vital="yes" Name="Second Service" DisplayName="Second Service" Description="Second Service" Start="auto" Account="NT AUTHORITY\LocalService" Interactive="no" ErrorControl="ignore" />
<ServiceControl Id="StartSecondService" Name="Second Service" Start="install" Wait="no" />
<ServiceControl Id="StopSecondService" Name="Second Service" Stop="both" Wait="yes" Remove="uninstall" />
</Component>
终于找到了解决方案。对于同一exe中的多个服务,您必须在ServiceInstall元素中设置Type=“shareProcess”,两个服务都可以正常工作。
我通过使用“InstallUtil”安装我的服务并比较注册表结构发现了这一点。“InstallUtil”将type设置为ownProcess,所以我也在安装程序中更改了我的类型,这很有吸引力
<Component Id="MyScheduler" Guid="{SOMEGUID}">
<File Id="MySchedulerEXE" Name="MyScheduler.exe" Source="MyScheduler.exe" KeyPath="yes" />
<ServiceInstall Id="FirstService" Type="shareProcess" Vital="yes" Name="First Service" DisplayName="First Service" Description="First Service" Start="auto" Account="NT AUTHORITY\LocalService" Interactive="no" ErrorControl="ignore" />
<ServiceControl Id="StartFirstService" Name="First Service" Start="install" Wait="no" />
<ServiceControl Id="StopFirstService" Name="First Service" Stop="both" Wait="yes" Remove="uninstall" />
<ServiceInstall Id="SecondService" Type="shareProcess" Vital="yes" Name="Second Service" DisplayName="Second Service" Description="Second Service" Start="auto" Account="NT AUTHORITY\LocalService" Interactive="no" ErrorControl="ignore" />
<ServiceControl Id="StartSecondService" Name="Second Service" Start="install" Wait="no" />
<ServiceControl Id="StopSecondService" Name="Second Service" Stop="both" Wait="yes" Remove="uninstall" />
</Component>
能否将WiX输出包括在内,以便我们更好地了解它是如何失败的?由于windows installer的性质,看起来这只能通过自定义操作来完成。我可以确认,使用自定义操作是可行的。感谢您的建议,但我认为困难的部分是,就是找到一种方法,让一个组件中的命令行参数随着每个功能的变化而变化。谢谢,这正是我所做的,并且它起到了作用。在我的例子中,有一个转折点:您可以选择要安装多少个服务实例。要做到这一点,我必须用独占条件复制整个组件;一个组件有一个安装/控制对,另一个有两个安装/控制对,另一个有三个安装/控制对,等等。我已经试过了,但无法让它工作。ServiceBase
数组中传递到ServiceBase.Run()
的第一个服务确实运行,但之后的服务不运行。有什么想法吗?我和法林哈有同样的想法。如果我使用“InstallUtil.exe”安装它,那么这两个服务都可以正常运行。但是wix安装程序只运行第一个。实际上,它不关心名称,它只运行第一个服务。有人请你找出问题的答案。对于同一exe中的多个服务,您必须在ServiceInstall元素中设置Type=“shareProcess”,两个服务都可以正常工作。
<?xml version="1.0" encoding="UTF-8"?>
<!-- The name of the product -->
<?define Service1Name = "Test Service1" ?>
<?define Service2Name = "Test Service2" ?>
<!-- The description of the product -->
<?define Service1Description = "Test Service1 that logs dummy text on an interval to a text file." ?>
<?define Service2Description = "Test Service2 that logs dummy text on an interval to a text file." ?>
<!-- The manufacturer, for setup package publisher and folder info -->
<?define Manufacturer = "Your Company" ?>
<!-- The version number of this setup package-->
<?define Version = "1.0.1" ?>
<!-- UpgradeCode must be unique and not changed once the first version of the program is installed. -->
<?define UpgradeCode = "{1240E0CD-B3D2-44A7-B064-11B3C0709D69}" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="$(var.Service1Name)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)" Version="$(var.Version)" Language="1033">
<!-- Create a folder inside Your Company called Test Service -->
<Package InstallerVersion="300" Compressed="yes"/>
<!-- Create a folder inside Your Company called Test Service -->
<Media Id="1" Cabinet="TestService.cab" EmbedCab="yes" />
<!-- Allow upgrades and prevent downgrades -->
<MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />
<!-- Define the directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<!-- Create a folder inside program files called Your Company -->
<Directory Id="ROOTDIRECTORY" Name="$(var.Manufacturer)">
<!-- Create a folder inside Your Company called Test Service -->
<Directory Id="INSTALLFOLDER" Name="$(var.Service1Name)" />
</Directory>
</Directory>
</Directory>
<!-- The files inside this DirectoryRef are linked to the Test Service directory via INSTALLFOLDER -->
<DirectoryRef Id="INSTALLFOLDER">
<!-- Create a single component which is the TestService.exe file -->
<Component Id="$(var.TestService1.TargetFileName)">
<!-- Copies the TestService.exe file using the project reference preprocessor variables -->
<File Id="$(var.TestService1.TargetFileName)" Source="$(var.TestService1.TargetPath)" KeyPath="yes" />
<!-- Remove all files from the INSTALLFOLDER on uninstall -->
<RemoveFile Id="RemoveService1" Name="*.*" On="both" />
<!-- Tell WiX to install the Service -->
<ServiceInstall Id="Service1Installer"
Type="ownProcess"
Name="TestService1"
DisplayName="$(var.Service1Name)"
Description="$(var.Service1Description)"
Start="auto"
ErrorControl="normal" />
<!-- Tell WiX to start the Service -->
<ServiceControl Id="StartService1" Start="install" Stop="both" Remove="uninstall" Name="TestService1" Wait="yes" />
</Component>
<!-- Create a single component which is the TestService.exe file -->
<Component Id="$(var.TestService2.TargetFileName)">
<!-- Copies the TestService.exe file using the project reference preprocessor variables -->
<File Id="$(var.TestService2.TargetFileName)" Source="$(var.TestService2.TargetPath)" KeyPath="yes" />
<!-- Remove all files from the INSTALLFOLDER on uninstall -->
<RemoveFile Id="RemoveService2" Name="*.*" On="both" />
<!-- Tell WiX to install the Service -->
<ServiceInstall Id="Service2Installer"
Type="ownProcess"
Name="TestService2"
DisplayName="$(var.Service2Name)"
Description="$(var.Service2Description)"
Start="auto"
ErrorControl="normal" />
<!-- Tell WiX to start the Service -->
<ServiceControl Id="StartService2" Start="install" Stop="both" Remove="uninstall" Name="TestService2" Wait="yes" />
</Component>
</DirectoryRef>
<!-- Tell WiX to install the files -->
<Feature Id="Feature1" Title="TestService1.Setup" Level="1">
<ComponentRef Id="$(var.TestService1.TargetFileName)" />
</Feature>
<Feature Id="Feature2" Title="TestService2.Setup" Level="1">
<ComponentRef Id="$(var.TestService2.TargetFileName)" />
</Feature>
</Product>
</Wix>