Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WiX: InstallService conditionally, but install file unconditionally

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!

like image 591
Crend King Avatar asked Aug 13 '10 11:08

Crend King


3 Answers

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.

like image 105
gtikok Avatar answered Oct 16 '22 11:10

gtikok


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.

like image 41
john Avatar answered Oct 16 '22 10:10

john


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.

like image 1
Christopher Painter Avatar answered Oct 16 '22 11:10

Christopher Painter