Frage MSBuild-Eigenschaftsumfang


Wiederkämpfe ich MSBuild. Ich möchte einen Eigenschaftswert mit einem Stammpfad definiert haben. Als Teil des Builds wird der Pfad mit Versionsinformationen aktualisiert. MSBuild scheint jedoch eigene Scoping-Regeln zu haben, die vollständig rückwärts laufen. Nimm dieses erste Beispiel:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

  <PropertyGroup>
    <MyPath>\\server\folder</MyPath>
  </PropertyGroup>

  <Target Name="Main">
    <Message Text="In Main Before - MyPath = $(MyPath)"/>
    <CallTarget Targets="Task1" />
    <CallTarget Targets="Task2" />
    <CallTarget Targets="Task3" />
    <Message Text="In Main After - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task1">
    <PropertyGroup>
        <MyPath>$(MyPath)\version5</MyPath>
    </PropertyGroup>
    <Message Text="In Task1 - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task2">
    <Message Text="In Task2 - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task3">
    <Message Text="In Task3 - MyPath = $(MyPath)"/>
  </Target>

</Project>

Hier ist die Ausgabe mit dieser Befehlszeile: msbuild PropertyScopeTest1.proj /target:Main 

Project "C:\Temp\PropertyScopeTest1.proj" on node 1 (Main target(s)).
Main:
  In Main Before - MyPath = \\server\folder
Task1:
  In Task1 - MyPath = \\server\folder\version5
Task2:
  In Task2 - MyPath = \\server\folder\version5
Task3:
  In Task3 - MyPath = \\server\folder\version5
Main:
  In Main After - MyPath = \\server\folder
Done Building Project "C:\Temp\PropertyScopeTest1.proj" (Main target(s)).

Nun, hier ist eine etwas andere Version, die die MyPath-Variable im Hauptziel setzt:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

  <PropertyGroup>
    <MyPath>\\server\path</MyPath>
  </PropertyGroup>

  <Target Name="Main">
    <Message Text="In Main Before - MyPath = $(MyPath)"/>
    <PropertyGroup>
        <MyPath>$(MyPath)\version5</MyPath>
    </PropertyGroup>
    <Message Text="In Main After PropertyGroup - MyPath = $(MyPath)"/>
    <CallTarget Targets="Task1" />
    <CallTarget Targets="Task2" />
    <CallTarget Targets="Task3" />
    <Message Text="In Main After - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task1">
    <Message Text="In Task1 - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task2">
    <Message Text="In Task2 - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="Task3">
    <Message Text="In Task3 - MyPath = $(MyPath)"/>
  </Target>

</Project>

Hier ist die Ausgabe mit dieser Befehlszeile: msbuild PropertyScopeTest2.proj /target:Main 

Project "C:\Temp\PropertyScopeTest2.proj" on node 1 (Main target(s)).
Main:
  In Main Before - MyPath = \\server\path
  In Main After PropertyGroup - MyPath = \\server\path\version5
Task1:
  In Task1 - MyPath = \\server\path
Task2:
  In Task2 - MyPath = \\server\path
Task3:
  In Task3 - MyPath = \\server\path
Main:
  In Main After - MyPath = \\server\path\version5
Done Building Project "C:\Temp\PropertyScopeTest2.proj" (Main target(s)).

Ich habe andere Links auf dieser Website untersucht, die ähnlich sind, aber alle scheinen den MSBuild-Task innerhalb der MSBuild-Projektdatei aufzurufen. Ich möchte nur den Pfad aktualisieren und überall im Projekt verfügbar machen. Irgendwelche Ideen?


20
2017-09-23 20:20


Ursprung


Antworten:


Aufbauend auf der Antwort von sll wird das Ziel, das den neuen Pfad festlegt, zu einer Abhängigkeit, anstatt sie zu verwenden CallTarget wird das erwartete Verhalten ergeben:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">

  <PropertyGroup>
    <MyPath>\\server\folder</MyPath>
  </PropertyGroup>

  <Target Name="Main" DependsOnTargets="SetMyPathProperty">
    <Message Text="In Main Before - MyPath = $(MyPath)"/>
    <CallTarget Targets="Task1" />
    <Message Text="In Main After - MyPath = $(MyPath)"/>
  </Target>

  <Target Name="SetMyPathProperty">
    <PropertyGroup>
      <MyPath>$(MyPath)\version5</MyPath>
    </PropertyGroup>
  </Target>

  <Target Name="Task1">
    <Message Text="In Task1 - MyPath = $(MyPath)"/>
  </Target>

</Project>

Build-Ausgabe:

Main:
  In Main Before - MyPath = \\server\folder\version5
Task1:
  In Task1 - MyPath = \\server\folder\version5
Main:
  In Main After - MyPath = \\server\folder\version5

Herstellung SetMyPathProperty eine Abhängigkeit von Aufgabe 1 Anstatt von Main führt zu einem identischen Verhalten wie PropertyScopeTest1.proj.


23
2017-09-26 16:47



Dies ist eine sehr interessante Frage, die im folgenden Artikel anhand von Beispielen eingehend untersucht wird: Umfang der Eigenschaften und des Elements in einem MSBuild-Skript

Grundsätzlich gibt es Tricks mit einem lokalen und globalen Kontextwechsel über eine Zielausführung:

  • Eine Instanz der Projektklasse wird für das Skript und erstellt   enthält alle Werte der Eigenschaften und Elemente in einem globalen   Kontext.
  • Wenn ein Ziel ausgeführt wird, wird der globale Kontext in einem lokalen Kontext kopiert   Kontext, der vom Ziel verwendet wird.
  • A Die Zielausführung endet, die lokalen Kontextaktualisierungen werden zusammengeführt   zurück zum globalen Kontext.
  • Bis eine Zielausführung abgeschlossen ist, sind die lokalen Aktualisierungen nicht verfügbar   Zugriff auf Ziele, die mit CallTarget- oder MSBuild-Tasks aufgerufen werden

17
2017-09-24 13:54