Comment obtenir que MSBUILD évalue et imprime le chemin complet lorsqu'un chemin relatif lui est attribué?

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

Question

Comment puis-je obliger MSBuild à évaluer et à imprimer dans une <Message /> tâche un chemin absolu étant donné un chemin relatif?

Groupe de propriétés

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

Tâche

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

Sortie

  

Copier '' vers 'c: \ Program Files (x86) \ Program \'

Était-ce utile?

La solution

Dans MSBuild 4.0 , le moyen le plus simple est le suivant:

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

Cette méthode fonctionne même si le script est <Import> édité dans un autre script; le chemin est relatif au fichier contenant le code ci-dessus.

(consolidé à partir de la réponse d'Aaron ainsi que de la dernière partie de Réponse de Sayed )

Dans MSBuild 3.5 , vous pouvez utiliser 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>

Sortie pertinente:

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

Un peu long quand vous me demandez, mais ça marche. Ce sera relatif à la & Quot; originale & Quot; fichier de projet, donc si placé dans un fichier qui obtient <=> ed, cela ne sera pas relatif à ce fichier.

Dans MSBuild 2.0 , il existe une approche qui ne résout pas & "; .. &"; Cependant, il se comporte comme un chemin absolu:

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

Le $ (MSBuildProjectDirectory) est réservé. La propriété est toujours le répertoire du script contenant cette référence.

Cela sera également relatif à & "original &"; fichier de projet, donc si placé dans un fichier qui obtient <=> ed, cela ne sera pas relatif à ce fichier.

Autres conseils

MSBuild 4.0 a ajouté les fonctions de propriété qui permettent d'appeler en mode statique. fonctionne dans certaines dll du système .net. Une très bonne chose à propos des fonctions de propriété est qu'elles vont évaluer en dehors d'une cible.

Pour évaluer un chemin complet, vous pouvez utiliser Système. IO.Path.GetFullPath lors de la définition d'une propriété telle que:

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

La syntaxe est un peu moche mais très puissante.

Wayne a raison de dire que les métadonnées connues ne s'appliquent pas aux propriétés, mais uniquement aux éléments. Utilisation de propriétés telles que & Quot; MSBuildProjectDirectory & Quot; fonctionnera, mais je ne connais pas de solution intégrée permettant de résoudre le chemin d'accès complet.

Une autre option consiste à écrire une tâche personnalisée simple qui prend un chemin relatif et extrait le chemin entièrement résolu. Cela ressemblerait à quelque chose comme ça:

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

Et vos lignes MSBuild ressemblent à quelque chose comme:

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

Vous essayez d'accéder à une propriété de métadonnées d'élément par l'intermédiaire d'une propriété, ce qui n'est pas possible. Ce que vous voulez faire est quelque chose comme ceci:

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

Ce qui générera une sortie sous la forme:

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

(Le script a été exécuté à partir de mon dossier Documents. \ Desktop est donc le chemin relatif correct pour accéder à mon bureau.)

Dans votre cas, remplacez le " .. \ Bureau " avec " ...... \ Public \ Server " dans l’élément Source_Dir et vous devriez être prêt.

Si vous devez convertir les propriétés en éléments, vous avez deux options. Avec msbuild 2, vous pouvez utiliser la tâche CreateItem

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

et avec MSBuild 3.5, vous pouvez avoir des ItemGroups dans une tâche

  <Target Name='Build'>
    <ItemGroup>
      <SRCDIR2 Include='$(Source_Dir)' />
    </ItemGroup>
    <Message Text="%(SRCDIR2.FullPath)" />
    <Message Text="%(SRCDIR.FullPath)" />
  </Target>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top