Jak mogę zmusić MSBUILD do oceny i wydrukowania pełnej ścieżki, gdy podano ścieżkę względną?

Jak mogę zmusić MSBuild do oceny i wydrukowania w zadaniu <Message /> ścieżki bezwzględnej podanej ścieżce względnej?

Grupa Własności

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

Zadanie

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

Wyjście

Kopiowanie " do "c:\Program Files(x86) \ Program\'

Author: Ruben Bartelink, 2008-10-07

5 answers

W MSBuild 4.0 najprostszym sposobem jest:

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

Ta metoda działa nawet jeśli skrypt jest <Import>edytowany do innego skryptu; ścieżka jest względem pliku zawierającego powyższy kod.

(skonsolidowana z odpowiedzi Aarona oraz ostatniej części odpowiedzi Sayeda)


W MSBuild 3.5 możesz użyć zadania ConvertToAbsolutePath:

<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>

Odpowiednie wyjście:

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

Trochę jak dla mnie, to z długimi włosami, ale to działa. Będzie to względne do "oryginalnego" pliku projektu, więc jeśli zostanie umieszczone wewnątrz pliku, który otrzyma <Import>ed, nie będzie to względne do tego pliku.


W MSBuild 2.0 istnieje podejście, które nie rozwiązuje"..". Jednak zachowuje się tak jak ścieżka absolutna:

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

Zastrzeżona właściwość $(MSBuildProjectDirectory) jest zawsze katalogiem skryptu, który zawiera to odniesienie.

To również jest względny do "oryginalnego" pliku projektu, więc jeśli zostanie umieszczony wewnątrz pliku, który otrzyma <Import>ed, nie będzie to względne do tego pliku.

 89
Author: Roman Starkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:22

MSBuild 4.0 dodał Funkcje Właściwości, które pozwalają na wywołanie funkcji statycznych w niektórych bibliotekach DLL systemu.NET. Naprawdę fajną rzeczą w funkcjach nieruchomości jest to, że będą one Oceniać stronę celu.

Do oceny pełnej ścieżki można użyć System. IO. Path. GetFullPath podczas definiowania właściwości w ten sposób:

<PropertyGroup>
  <Source_Dir>$([System.IO.Path]::GetFullPath('..\..\..\Public\Server\'))</Source_Dir>
</PropertyGroup>
Składnia jest trochę brzydka, ale bardzo potężna.
 31
Author: Aaron Carlson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-04 04:05:21

Wayne ma rację, że znane metadane nie dotyczą właściwości - tylko elementów. Używanie właściwości takich jak "MSBuildProjectDirectory" będzie działać, ale nie jestem świadomy wbudowanego sposobu rozwiązywania pełnej ścieżki.

Inną opcją jest napisanie prostego, niestandardowego zadania, które zajmie ścieżkę względną i wypluje ścieżkę w pełni rozwiązaną. Wyglądałoby to mniej więcej tak:

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;
    }
}

A Twoje Linie MSBuild wyglądałyby tak:

<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>
 6
Author: brock.holum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-07 03:32:33

Próbujesz uzyskać dostęp do właściwości metadanych elementu za pośrednictwem właściwości, co nie jest możliwe. To co chcesz zrobić to coś takiego:

<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>

Który wygeneruje wyjście jako:

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

(skrypt został uruchomiony z folderu Moje dokumenty, więc ..\Desktop jest poprawną ścieżką względną, aby dostać się do mojego pulpitu.)

W Twoim przypadku zastąp "..\Pulpit "z"......\Public \ Server " w pozycji Source_Dir i powinno być ustawione.

 5
Author: Scott Dorman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-07 03:38:19

Jeśli chcesz przekonwertować właściwości na elementy, masz dwie opcje. W msbuild 2 możesz użyć zadania CreateItem

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

I z MSBuild 3.5 możesz mieć ItemGroups wewnątrz zadania

  <Target Name='Build'>
    <ItemGroup>
      <SRCDIR2 Include='$(Source_Dir)' />
    </ItemGroup>
    <Message Text="%(SRCDIR2.FullPath)" />
    <Message Text="%(SRCDIR.FullPath)" />
  </Target>
 4
Author: Scott Weinstein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-07 16:24:50