2009-02-03 3 views
12

В настоящее время я интегрирую свои проекты Wix в MSBuild. Мне необходимо передать несколько значений проекту Wix. Одно значение будет работать (ProductVersion в примере ниже).Передача нескольких значений в свойство Wix DefineConstants с помощью MSBuild

Однако, как передать несколько значений в ключ DefineConstants? Я пробовал все «логические» разделители (пробел, запятая, полуколония, символ трубы), но это не работает.

С кем-то сталкивается с этой проблемой?

Решения, которые не работают:

  1. Попытка добавить элемент DefineConstants не работает, потому что DefineConstants должно быть выражено в атрибуте Properties.

ответ

11

Проблема:

Задача MSBuild (не MSBuild.exe, задача MSBuild имени MSBuild) не может обрабатывать несколько констант, используемых WIX проекты. Как правило, вы бы определить свойства в сценарии сборки, как:

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

Что вы видите, однако, глядя на журналы сборки является MSBuild отделяет константы и не сохраняет значения группируются вместе, как и следовало ожидать - подобный чтобы:

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

Так что, когда свеча пытается использовать эти константы он обычно реагирует с «ошибка CNDL0150:. Undefined переменной препроцессора„$ (var.SOMETHINGELSE)“Что это означает, что задача MSBuild не правильно обработки свойств, содержат несколько значений «=» в значении, даже если они группируются внутри кавычек. Без значения свойства сгруппированные в кавычки, они, очевидно, должны рассматриваться как отдельные свойства, а не одно значение.

Обойти:

Для того, чтобы решить эту проблему, вам нужно позвонить MSBuild.exe непосредственно и передать эти значения к нему вручную.

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

Это позволит получить ваш постоянную работу так, как вы хотите, чтобы они, без переделки проекта установки WiX.

Примечание: Если вы используете только одну константу, вы можете использовать задачу MSBuild следующим образом:

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

Существует способ сделать это, используя задачу MSBuild, вместо вызова exe: http://stackoverflow.com/questions/506687/defining-multiple-values-in-defineconstants-in-msbuild-element/4280454#4280454 –

+0

кажется, что если вы не используете msbuild 4, это способ пойти –

0

Я думаю, что что-то подобное должно работать.

 
<DefineConstants>DEBUG;TRACE</DefineConstants> 

Проверьте этот пост блога, чтобы узнать, может ли он помочь вам. http://www.sedodream.com/PermaLink,guid,9b1d23aa-6cb2-48cb-a47a-9cef29622676.aspx

Также проверьте это сообщение на форуме. Он решает аналогичную проблему, как ваша. http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/3f485bf4-1b00-48bf-b5d0-4b83341ce4a6/

+1

Это не работает, потому что DefineConstants должна быть выражена в атрибуте Properties. Он не работает как атрибут сам по себе. – Sardaukar

+0

Я обновил сообщение, посмотрим, поможет ли он сейчас. – Aamir

+0

Спасибо, но я уже прочитал обе эти статьи. Даже если первый работает, я все еще считаю его взломом, потому что проекты нужно строить два раза. – Sardaukar

-1

Почему вы указываете DefineContentants = ProductVersion = XXXXXX?

Для DefineConstants вы не назначаете значения, либо константа (например, DEBUG или TRACE) определена, либо нет. Это свойство относится к коммутатору компилятора /define C#. Что вы на самом деле пытаетесь сделать?

Также я не уверен, что вы имеете в виду, когда говорите, что мое сообщение в блоге - это «взломать» тот факт, что он был построен дважды - это весь смысл.

Сайед Ибрагим Хашими

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

+0

Сказал, я действительно купил вашу книгу, потому что я хотел лучше понять MSBuild. Я вернусь к вашему вопросу, когда закончу вашу книгу ;-) – Sardaukar

+0

@ Sardaukar Cool! :) –

+0

Wix перепрофилировал элемент DefineConstants как способ передачи пар имя-значение в препроцессор, поэтому вы назначаете значения. –

1

Я знаю MSDN документы полны ошибок, а иногда вводит в заблуждение: вот что он говорит о DefineConstants

Определяет условный компилятору константы. пары символов/значение разделенных точкой с запятой и , указанным с помощью следующих синтаксиса:

symbol1 = value1; symbol2 = value2

Это свойство эквивалентно коммутатору компилятора /.

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

Согласно MSDN, вы можете 1. определить несколько констант и 2. (@Sayed) присвоить значения

ОДНАКО я не мог получить ожидаемое поведение этого свойства Задача MSBuild работать так, как ожидалось, и рекомендовать временное решение Джеффа Винна, и его сообщение должно быть помечено как ответ.

+0

Готово. Спасибо за объяснение. – Sardaukar

0

Обходной способ взлома.

Предположения: возможные значения

  • SomeEnumValue являются EnumValue1 и EnumValue2

В MSBuild:

<DefineConstants>Debug;use_$(SomeEnumValue)</DefineConstants> 

В WiX:

<?ifdef $(var.use_EnumValue1) ?> 
    ... 
<?elseif $(var.use_EnumValue2) ?> 
    ... 
<?endif?> 
1

следующие работы для меня при использовании задачи MSBuild для создания Visual Studio Solution:

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

Уловка с помощью %3b, чтобы избежать ; разделителя внутри значения DefineConstants. Я не уверен, что это будет работать и для =. Может потребоваться их избежать как %3d, или он может вообще не работать ...

В элементе MSBuild также есть атрибут TargetAndPropertyListSeparators.Я не могу найти никакой документации для него, но возможно было бы использовать его для установки разделителя, отличного от ;.

+0

Это работает, когда вы передаете простые имена, такие как «debug» и «trace», но не тогда, когда вы хотите передавать пары имени и имени, такие как «config = debug; log = trace». –

0

Следующие строки работали, когда я включил их в файл .wixproj (используя Visual Studio 2010).

<PropertyGroup> 
    <DefineConstants>Const1=Value1;Const2=Value2;Const3=Value3</DefineConstants> 
</PropertyGroup> 
13

Проблема заключается в переходе пары имя-значение задачи MSBuild, а затем с MSBuild разобрать их должным образом, чтобы они могли быть переданы задачи свечи. Кажется, что MSBuild может обрабатывать список простых имен или одну пару имя-значение, но не список пар.

Мое решение состоит в том, чтобы уйти от списка, когда он передан в задачу MSBuild, и отменить его снова, когда он переходит к задаче «Свеча».

В файле MSBuild, определяют пары в собственности, как это:

<PropertyGroup> 
    <WixValues> 
     One=1; 
     Two=2; 
     Three=3; 
    </WixValues> 
</PropertyGroup> 

При вызове задачи MSBuild, спасаясь от собственности (требуется MSBuild 4):

<MSBuild 
    Projects="setup.wixproj" 
    Properties="WixValues=$([MSBuild]::Escape($(WixValues)))" /> 

неэкранированными должно быть сделано в файле wixproj, но нет необходимости редактировать файл вручную. Просто откройте свойства проекта, перейдите на вкладку Построение и где он говорит: «Определить переменные препроцессора», говоря:

$([MSBuild]::Unescape($(WixValues))) 

Это работает, даже если есть и другие переменные, уже в этом поле; просто добавьте это в список вместе с точкой с запятой.

Вы увидите в MSBuild журнал, что инструмент candle.exe принимает аргументы правильно:

candle.exe -dOne=1 -dTwo=2 -dThree=3 -dConfiguration=Release... 
2

Вы можете передать его в качестве параметра, а не постоянная. Код будет выглядеть следующим образом:

<MSBuild ... 
    Properties="ProductVersion=%(WixSetups.ISVersion)" /> 

В настоящее время в проекте WiX добавить постоянную:

<DefineConstants>BuildVersion=$(ProductVersion)</DefineConstants> 

И использовать его в * .wxs файл, где это необходимо:

$(var.BuildVersion) 

Например:

<Product Id="*" Name="My Company" Language="1033" Version="$(var.BuildVersion)"... /> 

Это будет работать с несколько параметров.

+0

DefineConstants !!! То что я отсутствовал. –

-1

Это сработало для меня и позволило мне передать предметы с еще не определенными парами ключей. Не самый элегантный, но я не кодер.

MSBuild test.proj/р: PassedInProp = "ProductVersion = 45; ВУ = 669; wewanttoknow = test5"

<?xml version="1.0" encoding="utf-8" ?> 
<Project ToolsVersion="4.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
<ItemGroup> 
    <test Include="$([MSBuild]::Unescape($(PassedInProp)))" /> 
    </ItemGroup> 
<Target Name ="Test"> 
    <CreateItem Include ="$([System.String]::New('%(test.identity)').Split('=')[0])" AdditionalMetadata="value=$([System.String]::New('%(test.identity)').Split('=')[1])"> 
     <Output TaskParameter="Include" ItemName ="Test2"/> 
    </CreateItem> 
    <Message Text ="Key: %(test2.identity) Value: %(test2.value)"/> 
    </Target> 
</Project> 
3

Я до сих пор было много хлопот получать эту работу, но peices каждого ответа выше, способствовали моему решению, поэтому я хотел поделиться.

Окружающая среда: TFS Build Server 2010 - Powershell, вызывающая MSBuild.exe Wix 3.6 установлен на сервере сборки

Цель состоит в том, чтобы передать номер сборки версии и 5 каталогов в MSBuild, так что Candle.exe получат их правильно

Моделировочные вызывает командный файл в конце сборки , и этот командный файл включает в себя шаг для вызова сценария powershell для сборки установщика Wix. Она проходит в номер версии для сборки и каталогов исходных и выходных (выход является Обменник ссылка UNC \ tfsbuildserver ..)

Чтобы заставить его работать, в ps1 файл Powershell,

  • использовать один/р: DefineConstants =, которая начинается с двойной "
  • закодировать все разделяющей; в% 3b
  • в = в порядке неперекодированный
  • не должно быть никаких дополнительных кавычки вокруг имен файлов с пробелами

    $msbuild = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" 
    
    $options = " /p:Configuration=Release /p:Platform=x64 " 
    $options = $options + " /p:DefineConstants=""" 
    $options = $options + "SolutionDir=" + $SourceDir 
    $options = $options + "%3bTFSBuildSourceLanding=" + $OutputLocation + "SharepointWebRoot\Landing" 
    $options = $options + "%3bTFSBuildSourceLandingAdmin=" + $OutputLocation + "SharepointWebRoot\LandingAdmin" 
    $options = $options + "%3bTFSBuildSourceRegistration=" + $OutputLocation + "Extranet_Registration" 
    $options = $options + "%3bTFSBuildSourceGAC=" + $OutputLocation + "GAC" 
    $options = $options + "%3bTFSBuildSourceSQL=" + $OutputLocation + "SQL" 
    $options = $options + "%3bProductVersion=" + $BuildVersion + """" 
    
    
    $build = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Build" 
    $clean = $msbuild + " ""EUM WIX\EUM Wix.wixproj"" " + $options + " /t:Clean" 
    
    
    Write-Host "Building Wix Installer..." 
    Invoke-Expression $clean 
    Invoke-Expression $build 
    
  • Внутри файла wixproj, мы должны экранирования в (на дне, где он говорит раскомментировать изменить)

    <Target Name="BeforeBuild"> 
         <CreateProperty Value="$([MSBuild]::Unescape($(DefineConstants)))"> 
         <Output TaskParameter="Value" PropertyName="DefineConstants" /> 
         </CreateProperty> 
        </Target> 
    
  • отметить также, что в Visual Studio, я буду использовать отладки настройки, и я могу установить значения по умолчанию для этих значений, на вкладке «Сборка», «Определить переменные препроцессора»

  • в настройках Release этот элемент должен быть пустым, поскольку он будет передан в командной строке выше.

0

Мое решение, чтобы избежать точкой с запятой, используя &#59;, таким образом:

<MSBuild 
    Projects="MyApplication.sln" 
    Properties="DefineConstants=Sources=$(OutputPath)\MyApplication\&#59;Configuration=$(Configuration)&#59;OutDir=$(OutputPath)\WiX\" 
    Targets="Clean;Rebuild" 
/> 
Смежные вопросы