0

Background

I have a Jenkins process where I build a Windows service and then use MSBuild to compile an .msi from a WiX project. The service itself does different processing based on what configuration it is running as, with this configuration determined by a number assigned to the service via the app.config. So, for example, FooService1 processes certain records, FooService2 other records, etc. The different versions are running the exact same compiled dlls, the only difference being the server number that is assigned in the app.config.

I will be running these different versions of the same service on the same machine, and would like to have the build process for the different variations of the service automated via Jenkins. I am using a powershell script to assign the service number in the app.config, and then passing in that service number via MSBuild and using a WiX variable to modify the name of the Windows service and the name of the folder the service operates out of.

Question/Issue

So the first MSBuild of the .wixproj goes fine. But then the next MSBuild reports that it is

Skipping target "Compile" because all output files are up-to-date with respect to the input files

Is there a way to "fake" MSBuild into thinking that it should compile the .wixproj again? My end goal is that if I want 3 versions of the service, Jenkins will compile the solution once and then build the WiX project 3 times, resulting in a /bin that contains FooService1.msi, FooService2.msi, and FooService3.msi. Each installer will contain the same dlls, but the app.config would be different.

bcwiniger
  • 159
  • 3
  • 11

1 Answers1

1

Build the service and MSI once, transform the config at install time.

Either bundle multiple config files in the MSI and overwrite at deployment time like in this answer. Or pass in the desired value at install time and use a property and XML transform to update the file. Building multiple MSI's for a single config value is overkill.

To pass the value at install time you can do something like this

Say you have a value in an app settings section

<appSettings>
    <add key="ServiceType" value="1" />
</appSettings>

Add the wixUtil library

<Wix
    xmlns="http://schemas.microsoft.com/wix/2006/wi"
    xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

In the Product element in your Wix add a property element

<Property Id="SERVICETYPE" Value="25"/>

Note that the property Id should be in upper case (this makes the property public)

Then add this in your product element

<util:XmlFile
    Id="UpdateServiceType"
    Action="setValue"
    File="[INSTALLFOLDER]MyService.exe.config"
    SelectionLanguage="XPath"
    Permanent="yes"
    ElementPath="/configuration/appSettings/add[\[]@key='ServiceType'[\] ]/@value"
    Value="[SERVICETYPE]" />

You can then pass in SERVICETYPE at install time ie.

MyMSI.msi SERVICETYPE=2

Community
  • 1
  • 1
James Reed
  • 13,873
  • 51
  • 60
  • I like that this is a cleaner, more self contained way to modify the config file. But it doesn't seem to address the issue of needing to have several versions of the same service running on the same machine. I need to be able to have a separate service for each service type. So in the end I could check my process manager for that machine and see FooService1, FooService2, etc. That is why I was trying to generate multiple installers containg the same dlls. – bcwiniger Oct 12 '16 at 22:02
  • 1
    You could use the same technique to add a property for the service name as well. Should be even easier as you don't need the xslt. – James Reed Oct 12 '16 at 22:13
  • Oh great! So I could change the service name and the directory that the service operates out of in one swoop. That makes life much easier. – bcwiniger Oct 12 '16 at 22:16
  • 1
    Yep, it's been a while since I've messed around with MSI's but you should be able to pass in the install directory without changing your wix. See [this](http://stackoverflow.com/a/8841965/568475) answer – James Reed Oct 12 '16 at 22:25