Comment puis-je demander à MSBuild d'évaluer et d'imprimer dans un <Message />
charger un chemin absolu avec 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
Copie de '' vers 'c:\Program Files (x86)\Program \'
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>
ed dans un autre script; le chemin est relatif au fichier contenant le code ci-dessus.
(consolidé de réponse d'Aaron ainsi que la dernière partie de réponse de Sayed )
Dans MSBuild 3.5 , vous pouvez utiliser la tâche 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 si vous me demandez, mais ça marche. Ce sera relatif au fichier de projet "d'origine", donc s'il est placé dans un fichier qui obtient <Import>
ed, cela ne sera pas relatif à ce fichier.
Dans MSBuild 2.0 , il existe une approche qui ne résout pas "..". Il se comporte cependant comme un chemin absolu:
<PropertyGroup>
<Source_Dir_Abs>$(MSBuildProjectDirectory)\$(Source_Dir)</Source_Dir_Abs>
</PropertyGroup>
La propriété réservée $ (MSBuildProjectDirectory) est toujours le répertoire du script qui contient cette référence.
Ce sera également relatif au fichier de projet "d'origine", donc s'il est placé dans un fichier qui obtient <Import>
ed, cela ne sera pas relatif à ce fichier.
MSBuild 4.0 a ajouté Fonctions de propriété qui vous permettent d'appeler des fonctions statiques dans certaines des DLL du système .net. Une très bonne chose à propos des fonctions de propriété est qu'elles évalueront en dehors d'une cible.
Pour évaluer un chemin complet, vous pouvez utiliser System.IO.Path.GetFullPath lors de la définition d'une propriété comme ceci:
<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 bien connues ne s'appliquent pas aux propriétés - uniquement aux éléments. L'utilisation de propriétés telles que "MSBuildProjectDirectory" fonctionnera, mais je ne connais pas de méthode intégrée pour résoudre le chemin d'accès complet.
Une autre option consiste à écrire une tâche simple et personnalisée qui prendra un chemin relatif et crachera 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>
Vous essayez d'accéder à une propriété de métadonnées d'élément via une propriété, ce qui n'est pas possible. Ce que vous voulez faire, c'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>
Qui générera une sortie comme:
Copying 'C:\Users\sdorman\Desktop' to 'c:\Program Files (x86)\Program\'
(Le script a été exécuté à partir de mon dossier Documents, donc ..\Desktop est le chemin relatif correct pour accéder à mon bureau.)
Dans votre cas, remplacez le "..\Desktop" par "......\Public\Server" dans l'élément Source_Dir et vous devriez être prêt.
Si vous devez convertir des 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 groupes d’éléments dans une tâche
<Target Name='Build'>
<ItemGroup>
<SRCDIR2 Include='$(Source_Dir)' />
</ItemGroup>
<Message Text="%(SRCDIR2.FullPath)" />
<Message Text="%(SRCDIR.FullPath)" />
</Target>