views:

1318

answers:

4

Good day

I am a student developer and I have built several installers for the company I am working with now. So I am fairly familure with WIX. We recently decided to have a Build server that auto builds our solution. It builds both debug, and release, aswell as Obfuscated(and non obfuscated) projects. And you really don't have to understand any of this. All you have to understand is that I have the same Wix project building different MSIs dynamicaly. So the way we build them is we call MSBuild.exe with several parameters. Parameters the wix project depends on.

so lets say we go into command prompt and write C:>\windows\Microsoft.NET\Framework\v3.5\MSBuild.exe MyApp.Install\MyApp.Install.wixproj /p:Configuration=Release /p:SpecialPath=Obfuscated /t:Build

The idea is that wix sees the "SpecialPath" parameter being assigned "Obfuscated"; and in then the installer paths its source to ..\myApp\bin\$(var.SpecialPath)\myApp.exe which translates to ..\myApp\bin\Obfuscated\myApp.exe when built.

So my question is how do you create those custom build parameters and have them passed to my .wxs file. As of now with ^this^ setup, $(var.SpecialPath) is not defined and the build CrashSplosions.

For obvious legal reasons I had to cut 90% of the project.wxs file out and rename some stuff, but for all intensive purposes this is what I have.

<Directory Id="TARGETDIR" Name="SourceDir" >
  <Directory Id="ProgramFilesFolder">
    <Directory Id="INSTALLLOCATION" Name="myApp"> 

      <Component Id="myAppEXE" Guid="FD5EBC02-MY29-GUID-ACCA-61324C5F1B68">
        <RegistryKey Root="HKLM" Key="Software\MyApp">
          <RegistryValue Value="0" Type="string" KeyPath="yes"/>
        </RegistryKey>
        <File Id="MYAPPEXE" Name='myApp.exe' Source="..\myApp\bin\$(var.SpecialPath)\myApp.exe" />
      </Component>

      <Component Id="EngineDLL" Guid="*">
        <File Id="ENGINEDLL" Name='Engine.dll' Source="..\myApp\bin\$(var.Configuration)\Engine.dll" />
      </Component>
      <Component Id="CommonDLL" Guid="*">
        <File Id="COMMONDLL" Name='Common.dll' Source="..\myApp\bin\$(var.Configuration)\Common.dll" />
      </Component>

    </Directory>
  </Directory>
</Directory>

<Feature Id="ProductFeature" Title="myApp" Description='All' Display='expand' Level="1" ConfigurableDirectory='INSTALLLOCATION'>
  <ComponentRef Id="myAppEXE" />
  <ComponentRef Id="EngineDLL" />
  <ComponentRef Id="CommonDLL" />
</Feature>

+5  A: 

The reason it's not working for you is that you are setting msbuild properties on the command line, which are not getting passed through as wix variables. MSBuild properties and wix variables are two different concepts.

One way to fix this is to ignore the concept of msbuild properties and use environment variables to pass values directly to candle.exe. You can use environment variables in your wxs file like this:

$(env.SpecialPath)

You can then launch your setup build from a batch file which prepares the necessary environment variables like this:

@echo off
setlocal

set SpecialPath=foo
set Configuration=Release
set msbuild=C:\windows\Microsoft.NET\Framework\v3.5\MSBuild.exe

%msbuild% test.wixproj /t:Build || goto ERROR

exit /b 0

:ERROR
echo Failed to build setup!
exit /b 1

Alternatively, if you prefer to pass parameters via msbuild properties, you should first take a look at the msbuild candle task documentation. It shows you can set values in your wixproj file like this:

<DefineConstants>Variable1=value1;Variable2=value2</DefineConstants>

This still requires you to hardcode values in the wixproj file though. If you want to pass the values as msbuild properties on the command line, then you should probably do something like this:

<DefineConstants>Variable1=$(value1);Variable2=$(value2)</DefineConstants>

and then pass /p:value1=foo /p:value2=bar on the command line, or define these msbuild properties elsewhere.

Wim Coenen
+1  A: 

As already answered, you need to pass the variables into WiX. We use Nant instead of MSBuild, but the concept remains the same.

Here's a Nant example passing in half a dozen variables to candle (it's not the cleanest example, but is lifted verbatim from a project I worked on)

<candle   out="${dir.obj}\"
          rebuild="true"
          extensions="WixUIExtension;WixNetFxExtension">
    <defines>
        <define name="ProcessorArchitecture" value="${release.platform}" />
        <define name="SourceDir" value="${dir.source}" />
        <define name="version" value="${version}" />
        <define name="releasetype" value="${release.type}" />
        <define name="Language" value="${language}" />
        <define name="product" value="${string.product}" />
        <define name="productedition" value="${release.productedition}" />
    </defines>

    <sources>
        <include name="*.wxs" />
        <include name="..\Common\*.wxs" />
    </sources>
</candle>

<!-- Define fallback culture for non-US -->
<property name="cultures" value="${language}" />
<property name="cultures" value="${language};en-US" unless="${language == 'en-US'}" />

<light
  out="${dir.build}\setup_${release.platform}_${release.compressionlevel}.msi"
  extensions="WixUIExtension;WixNetFxExtension;WixUtilExtension"
  cultures="${cultures}"
  rebuild="true"
  suppressices="ICE03;ICE82"
  suppresspdb="true" >


    <arg line="-loc &quot;setup-${language}.wxl&quot;" />
    <arg line="-sw1101" />

    <arg line="-b ${dir.resources}" />
    <arg line="-b ${dir.resources.common}" />
    <arg line="-b ${dir.resources.common}\Microsoft" />
    <arg line="-b ${dir.source}" />
    <arg line="-dcl:${release.compressionlevel}" />
    <arg line="-dWixUILicenseRtf=EULA_${language}.rtf" />
    <sources>
        <include name="${dir.obj}\*.wixobj" />
    </sources>
</light>
sascha
A: 

Thanks so much guys; that worked like a charm. Also giving me a broader understanding of Wix.

Cheer, Chris

Christopher Roy
A: 

Hi Christopher,

Can you share some of your knowledge of Passing build parameters to .wxs file to dynamicaly build wix installers? I am trying to achieve something very similar. In my situation, i have to create MSIs on the build servers which will install web applications(content + IIS config). I need to pass the IIS configuration dynamically for each application.

your help will be highly appreciated.

regards,

Pavan

rauts