Passing multiple values to Wix DefineConstants property with MSBuild

后端 未结 12 1918
萌比男神i
萌比男神i 2020-12-08 05:42

I\'m currently integrating my Wix projects in MSBuild. It is necessary for me to pass multiple values to the Wix project. One value will work (ProductVersion in the sample b

相关标签:
12条回答
  • 2020-12-08 06:07

    The problem:

    The MSBuild task (not MSBuild.exe, the MSBuild task named MSBuild) cannot handle multiple constants used by WIX projects. Normally you would specify the properties in your build script like:

    <MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1;SOMETHINGELSE=2&quot;" />
    

    What you see however, when looking at the build logs is the MSBuild separates the constants and does not keep the values grouped together like you would expect - similar to:

    Task "MSBuild" Global Properties:
    Configuration=MyConfig
    Platform=x86
    DefineConstants="SOMETHING=1
    SOMETHINGELSE=2"
    

    So when candle tries to use those constants it typically responds with "error CNDL0150: Undefined preprocessor variable '$(var.SOMETHINGELSE)'. What this means is the MSBuild task is not properly handling properties which contain multiple '=' in the value even when grouped within quotation marks. Without the property value being grouped in quotation marks, they should obviously be treated as separate properties, rather than a single value.

    The workaround:

    In order to fix this problem, you need to call MSBuild.exe directly and pass those values to it manually.

    msbuild.exe /p:Configuration=MyConfig /p:Platform=x86 /p:DefineConstants="SOMETHING=1;SOMETHINGELSE=2" YourSolution.sln
    

    This will get your constants the work the way you want them to, without having to redesign your WiX installation project.

    NOTE: If you're only using a single constant you can still use the MSBuild task like so:

    <MSBuild Projects="YourSolution.sln" Properties="Configuration=MyConfig;Platform=x86;DefineConstants=&quot;SOMETHING=1&quot;" />
    
    0 讨论(0)
  • 2020-12-08 06:07

    I think something like this should work.

     <DefineConstants>DEBUG;TRACE</DefineConstants> 
    

    Check this blog post to see if it can help you out. http://www.sedodream.com/PermaLink,guid,9b1d23aa-6cb2-48cb-a47a-9cef29622676.aspx

    Also check this forum post. It solves a similar problem as yours. http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/3f485bf4-1b00-48bf-b5d0-4b83341ce4a6/

    0 讨论(0)
  • 2020-12-08 06:15

    Why are you specifying DefineContstants=ProductVersion=XXXXXX?

    For DefineConstants you are not assigning values, either a constant (like DEBUG or TRACE) is defined or it is not. This property relates to the /define C# compiler switch. What are you really trying to do?

    Also I'm not sure what you mean when you say tha my blog post is a "hack" the fact that it was built twice is the whole point.

    Sayed Ibrahim Hashimi

    My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

    0 讨论(0)
  • 2020-12-08 06:17

    The following works for me when using an MSBuild task to build a Visual Studio Solution:

    <MSBuild Projects="Solution.sln"
             Targets="Rebuild"
             Properties="Configuration=Debug;DefineConstants=DEBUG%3bTRACE" />
    

    The trick is using %3b to escape the ; separator inside the DefineConstants value. I'm not sure if this will work for the = too. They may need to be escaped as %3d or it may not work at all...

    There's also a TargetAndPropertyListSeparators attribute on the MSBuild element. I can't find any documentation for it but it might be possible to use it to set a separator other than ;.

    0 讨论(0)
  • 2020-12-08 06:20

    I know MSDN docs are full of errors and sometimes misleading: here is what it says about DefineConstants

    Defines conditional compiler constants. Symbol/value pairs are separated by semicolons and are specified by using the following syntax:

    symbol1 = value1 ; symbol2 = value2

    The property is equivalent to the /define compiler switch.

    http://msdn.microsoft.com/en-us/library/bb629394.aspx

    According to MSDN, you can 1. define multiple constants and 2. (@Sayed) assign values

    HOWEVER I could not get the expected behaviour of this property of the MSBuild task to work as expected and recommend Jeff Winn's workaround, and his post should be marked as the answer.

    0 讨论(0)
  • 2020-12-08 06:25

    My solution is to escape the semicolon using &#59;, this way:

    <MSBuild
        Projects="MyApplication.sln"
        Properties="DefineConstants=Sources=$(OutputPath)\MyApplication\&#59;Configuration=$(Configuration)&#59;OutDir=$(OutputPath)\WiX\"
        Targets="Clean;Rebuild"
    />
    
    0 讨论(0)
提交回复
热议问题