In Windows Install XML toolset, to install a service, we group <ServiceInstall>
with a <File>
in a <Component>
. To conditionally install the service, we put <Condition>
under the <Component>
. However if the condition is false, the file will not be installed too. If I put the <File>
in an unconditional <Component>
, then the service has no executable file path and thus installation will fail. If I put the <File>
in both <Component>
, duplicate symbols will be found.
The question is, can we install a service conditionally, but install the associated executable file unconditionally?
Thanks!
Create two components with the different GUIDs' and Ids' and mutually exclusive conditions: one for the file and service, and another for file only. Something like this:
<Component Id="SvcComp" Guid="{YOUR-GUID}" SharedDllRefCount="yes">
<Condition> SOME_CONDITION </Condition>
<File Id="SvcFile" Name="Service.exe" Source="Service.exe" Vital="yes" />
<ServiceInstall Id="Svc" Name="Service" DisplayName="Service" Description="Service" Type="ownProcess" Start="auto" ErrorControl="normal" Vital="yes" />
<ServiceControl Id="Svc" Name="Service" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
<Component Id="ExeComp" Guid="{YYOUR-GUID}" SharedDllRefCount="yes" >
<Condition> NOT SOME_CONDITION </Condition>
<File Id="ExeFile" Name="Service.exe" Source="Service.exe" Vital="yes" />
</Component>
You will get a LGHT1076 warning which could be suppressed since the conditions in the components are mutually exclusive.
If you only have one service, you can condition out the service actions in the InstallExecuteSequence
table.
Alternatively, you have to have a CA run during immediate phase, that temporarily removes the entry from the service tables prior to execution during deferred.
I am not a fan of splitting the dll for no reason.
I've been down this road and it gets complicated faster then one would expect.
I consider having two components (despite their mutually exclusive conditional expressions) with the same keyfile but different ServiceInstall/Control resources a component rule violation.
The way I suggest doing it is move all of your business logic into a seperate DLL component and create two different EXE components. Set one up as a console/windows app and the other as a service app. Assocate the components to two different features so that the end user can decide which way he wants to configure the application. The user can then do a modify operation in add/remove programs and use MSI to change his mind later also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With