Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Installing a multi-file NT Service using WiX (2.0)

How do I install a service with some additional files in WiX, and define what file is the actual service EXE file?

Scenario: I had a service which was just a single EXE file, and installed it as a Windows NT service in WiX with this code:

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

and I had a feature which would then allow to install and optionally start this service.

Now, my problem is - now my service has grown, and the single EXE is no longer a single EXE - it's multiple files, EXE, DLL, and a few support files.

However, how can I install that now??

I tried to have a component with all my files

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

First, I tried to just add the ServiceInstall and ServiceControl tags to this component:

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

but then my "Framework.dll" gets set as the source path for the service being created........

So I thought I'd create a second component to actually install the service, using ServiceInstall, and I'd just reference that service EXE file using FileRef - but that doesn't seem to exist (at least in 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>

So - what is a poor WiX author gotta do to install all the necessary files, and still get the NT Service installation to pick up the correct EXE file (not just any arbitrary file from the component's list of files) ??

Marc

like image 784
marc_s Avatar asked Aug 12 '09 13:08

marc_s


1 Answers

The ServiceInstall element will end up pointing to the "KeyPath" of the Component the ServiceInstall is in. By default the WiX toolset picks the first File or RegistryKey element in your Component as the KeyPath. When you added files to your Component, the .dll at the top of the list became the KeyPath.

In general, smaller Components are better than bigger ones. So a better solution would be to place your DLLs in separate Components. Then you can leave the .exe File element and the ServiceInstall element in the same Component. That makes it all very clean.

If you then want the "service" grouped together, you can create a ComponentGroup element and put ComponentRefs to the .exe and .dll Components. Now you have a single thing you can reference from a Feature/ComponentGroupRef.

like image 181
Rob Mensching Avatar answered Sep 18 '22 11:09

Rob Mensching