55 votes

Comment puis-je faire en sorte que MSBUILD évalue et imprime le chemin complet lorsqu'il reçoit un chemin relatif ?

Comment puis-je faire en sorte que MSBuild évalue et imprime dans une <Message /> tâche un chemin absolu donné un chemin relatif ?

Groupe de propriété

<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

Copie de " " à " c " : \Program Fichiers (x86) \Program\ '

95voto

romkyns Points 17295

Dans MSBuild 4.0 La méthode la plus simple est la suivante :

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

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

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


Dans MSBuild 3.5 vous pouvez utiliser l'option ConvertToAbsolutePath tâche :

<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 longuet si vous voulez mon avis, mais ça marche. Ce sera relatif au fichier de projet "original", donc si placé dans un fichier qui obtient <Import> ed, ce ne sera pas relatif à ce fichier.


Dans MSBuild 2.0 il existe une approche qui ne résout pas " ". Elle se comporte cependant comme un chemin absolu :

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

En $(MSBuildProjectDirectory) La propriété réservée est toujours le répertoire du script qui contient cette référence.

Il sera également relatif au fichier de projet "original", donc s'il est placé à l'intérieur d'un fichier qui reçoit l'extension <Import> ed, ce ne sera pas relatif à ce fichier.

31voto

Aaron Carlson Points 1742

MSBuild 4.0 ajouté Fonctions de propriété qui vous permettent d'appeler des fonctions statiques dans certaines des dlls du système .net. L'avantage des fonctions de propriété est qu'elles peuvent être évaluées 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é comme celle-ci :

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

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

6voto

brock.holum Points 1745

Wayne a raison de dire que les métadonnées connues ne s'appliquent pas aux propriétés, mais uniquement aux éléments. L'utilisation de propriétés telles que "MSBuildProjectDirectory" fonctionnera, mais je n'ai pas connaissance d'un moyen intégré de résoudre le chemin complet.

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

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

5voto

Scott Dorman Points 25000

Vous essayez d'accéder à une propriété de métadonnées d'élément par le biais 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 va générer une sortie comme :

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

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

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

4voto

Scott Weinstein Points 11404

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

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

et avec MSBuild 3.5, vous pouvez avoir des ItemGroups à l'intérieur d'une tâche.

  <Target Name='Build'>
    <ItemGroup>
      <SRCDIR2 Include='$(Source_Dir)' />
    </ItemGroup>
    <Message Text="%(SRCDIR2.FullPath)" />
    <Message Text="%(SRCDIR.FullPath)" />
  </Target>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X