Wie kann ich MSBUILD den vollständigen Pfad zu bewerten und zu drucken, wenn Sie einen relativen Pfad gegeben?

StackOverflow https://stackoverflow.com/questions/176931

Frage

Wie kann ich MSBuild zu bewerten und in einer <Message /> Aufgabe ein absoluter Pfad angegeben einen relativen Pfad drucken?

Property Group

<Source_Dir>..\..\..\Public\Server\</Source_Dir>
<Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>

Task

<Message Importance="low" Text="Copying '$(Source_Dir.FullPath)' to '$(Program_Dir)'" />

Output

  

Kopieren '' bis 'c: \ Program Files (x86) \ Programme \'

War es hilfreich?

Lösung

In MSBuild 4.0 , der einfachste Weg ist die folgende:

$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)\your\path'))

Diese Methode funktioniert auch, wenn das Skript in ein anderes Skript <Import>ed wird; der Pfad ist in Bezug auf die Datei, um den obigen Code enthält.

(von Aaron Antwort konsolidiert sowie der letzte Teil der Sayed Antwort )


In MSBuild 3.5 , können Sie die ConvertToAbsolutePath Aufgabe:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         DefaultTargets="Test"
         ToolsVersion="3.5">
  <PropertyGroup>
    <Source_Dir>..\..\..\Public\Server\</Source_Dir>
    <Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
  </PropertyGroup>

  <Target Name="Test">
    <ConvertToAbsolutePath Paths="$(Source_Dir)">
      <Output TaskParameter="AbsolutePaths" PropertyName="Source_Dir_Abs"/>
    </ConvertToAbsolutePath>
    <Message Text='Copying "$(Source_Dir_Abs)" to "$(Program_Dir)".' />
  </Target>
</Project>

Relevante Ausgabe:

Project "P:\software\perforce1\main\XxxxxxXxxx\Xxxxx.proj" on node 0 (default targets).
  Copying "P:\software\Public\Server\" to "c:\Program Files (x86)\Program\".

Ein wenig langatmig, wenn Sie mich fragen, aber es funktioniert. Dies wird die „Original“ Projektdatei relativ sein, so dass, wenn in einer Datei abgelegt, die <Import>ed werden, wird dies nicht auf diese Datei relativ sein.


In MSBuild 2.0 gibt es einen Ansatz, der nicht löst "..". Es ist jedoch verhalten sich wie ein absoluter Pfad:

<PropertyGroup>
    <Source_Dir_Abs>$(MSBuildProjectDirectory)\$(Source_Dir)</Source_Dir_Abs>
</PropertyGroup>

Die $ (MSBuildProjectDirectory) reserviert Eigentum ist immer das Verzeichnis des Skripts, das diese Referenz enthält.

Dies wird auch auf die „Original“ Projektdatei relativ sein, so dass, wenn in einer Datei abgelegt, die <Import>ed werden, wird dies nicht auf diese Datei relativ sein.

Andere Tipps

MSBuild 4.0 hinzugefügt Eigenschaftsfunktionen die Ihnen erlauben, in statische anrufen Funktionen in einigen der .net-System-DLLs. Eine wirklich nette Sache über Property-Funktionen ist, dass sie Seite eines Ziel bewerten out wird.

Um einen vollständigen Pfad auswerten können Sie -System verwenden. IO.Path.GetFullPath wenn eine Eigenschaft wie so definieren:

<PropertyGroup>
  <Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>

Die Syntax ist ein wenig hässlich, aber sehr mächtig.

Wayne ist richtig, dass bekannte Metadaten nicht auf Eigenschaften gelten - nur auf Posten. Mit Eigenschaften wie „MSBuildProjectDirectory“ wird funktionieren, aber ich bin mir nicht bewusst ein in Art und Weise gebaut, um den vollständigen Pfad zu lösen.

Eine weitere Möglichkeit ist eine einfache, individuelle Aufgabe zu schreiben, die einen relativen Pfad nehmen und den vollständig aufgelösten Pfad ausspucken. Es würde wie folgt aussehen:

public class ResolveRelativePath : Task
{
    [Required]
    public string RelativePath { get; set; }

    [Output]
    public string FullPath { get; private set; }

    public override bool Execute()
    {
        try
        {
            DirectoryInfo dirInfo = new DirectoryInfo(RelativePath);
            FullPath = dirInfo.FullName;
        }
        catch (Exception ex)
        {
            Log.LogErrorFromException(ex);
        }
        return !Log.HasLoggedErrors;
    }
}

Und Ihre MSBuild Linien würden etwas wie folgt aussehen:

<PropertyGroup>
    <TaskAssembly>D:\BuildTasks\Build.Tasks.dll</TaskAssembly>
    <Source_Dir>..\..\..\Public\Server\</Source_Dir>
    <Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<UsingTask AssemblyFile="$(TaskAssembly)" TaskName="ResolveRelativePath" />

<Target Name="Default">
    <ResolveRelativePath RelativePath="$(Source_Dir)">
    <Output TaskParameter="FullPath" PropertyName="_FullPath" />
    </ResolveRelativePath>
    <Message Importance="low" Text="Copying '$(_FullPath)' to '$(Program_Dir)'" />
</Target>

Sie versuchen, ein Element Metadateneigenschaft durch eine Eigenschaft zuzugreifen, was nicht möglich ist. Was Sie tun möchten, ist so etwas wie folgt aus:

<PropertyGroup>
  <Program_Dir>c:\Program Files (x86)\Program\</Program_Dir>
</PropertyGroup>
<ItemGroup>
   <Source_Dir Include="..\Desktop"/>
</ItemGroup>     
<Target Name="BuildAll">
   <Message Text="Copying '%(Source_Dir.FullPath)' to '$(Program_Dir)'" />
</Target>

Welche erzeugen ausgegeben als:

 Copying 'C:\Users\sdorman\Desktop' to 'c:\Program Files (x86)\Program\'

(Das Skript wurde von Ordner Eigene Dateien ausführen, so .. \ Desktop ist die richtige relative Pfad auf meinem Desktop zu erhalten.)

In Ihrem Fall, ersetzen Sie den ".. \ Desktop" mit "...... \ Public \ Server" in dem SOURCE_DIR Artikel und Sie sollten alle eingestellt werden.

Wenn Sie Eigenschaften, um Objekte konvertieren müssen haben Sie zwei Möglichkeiten. Mit msbuild 2, können Sie die CreateItem Aufgabe

  <Target Name='Build'>
    <CreateItem Include='$(Source_Dir)'>
      <Output ItemName='SRCDIR' TaskParameter='Include' />
    </CreateItem>

und mit MSBuild 3.5 können Sie ItemGroups innerhalb einer Aufgabe haben

  <Target Name='Build'>
    <ItemGroup>
      <SRCDIR2 Include='$(Source_Dir)' />
    </ItemGroup>
    <Message Text="%(SRCDIR2.FullPath)" />
    <Message Text="%(SRCDIR.FullPath)" />
  </Target>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top