Как я могу получить MSBUILD для оценки и печати полного пути при заданном относительном пути?


как я могу получить MSBuild для оценки и печати <Message /> задание абсолютного пути с учетом относительного пути?

Группа В Собственность

<Source_Dir>......PublicServer</Source_Dir>
<Program_Dir>c:Program Files (x86)Program</Program_Dir>

задание

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

выход

копирование " в 'c:Program файлы (x86)Program'

5 54

5 ответов:

В MSBuild 4.0 самый простой способ заключается в следующем:

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

этот метод работает, даже если скрипт <Import>ed в другой скрипт; путь относительно файла, содержащего приведенный выше код.

(сводное от Аарона!--15--> а также последняя часть ответ Саида)


В MSBuild 3.5 можно использовать 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>

соответствующие выход:

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

немного многословно, если вы спросите меня, но работает. Это будет относительно "исходного" файла проекта, поэтому, если он помещен внутрь файла, который получает <Import>ЭД, это не будет связано с этим файлом.


В MSBuild 2.0 есть подход, который не решает "..". Однако он ведет себя так же, как абсолютный путь:

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

в $(MSBuildProjectDirectory) зарезервированное свойство всегда является каталогом скрипта, содержащего эту ссылку.

это также будет относительно "исходного" файла проекта, поэтому, если он помещен внутрь файла, который получает <Import>ЭД, это не будет связано с этим файлом.

MSBuild 4.0 добавлено Функции Собственность, которые позволяют вам вызывать статические функции в ряд .чистые DLL файлов системы. Действительно хорошая вещь о функциях свойств заключается в том, что они будут оценивать внешнюю сторону цели.

чтобы оценить полный путь, вы можете использовать System.IO.Path. GetFullPath при определении свойства следующим образом:

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

синтаксис немного уродливый, но очень мощный.

Уэйн прав, что хорошо известные метаданные не применяются к свойствам-только к элементам. Использование свойств, таких как" MSBuildProjectDirectory " будет работать, но я не знаю встроенного способа разрешения полного пути.

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

и ваши строки MSBuild будут выглядеть примерно так:

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

вы пытаетесь получить доступ к свойству метаданных элемента через свойство, что невозможно. Что вы хотите сделать, это что-то вроде этого:

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

который будет генерировать вывод как:

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

(скрипт был запущен из папки "Мои документы", так ..\Desktop-это правильный относительный путь к моему рабочему столу.)

в вашем случае, заменить "..\Рабочий стол" с "......\Public\Server " в элементе Source_Dir, и вы должны быть все настроены.

Если вам нужно преобразовать свойства предметов, у вас есть два варианта. С msbuild 2, Вы можете использовать CreateItem задание

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

и с MSBuild 3.5 вы можете иметь ItemGroups внутри задачи

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