如何让MSBuild在<Message />任务中评估和打印给定相对路径的绝对路径?

物业组

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

<强>任务

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

<强>输出

  

将''复制到'c:\ Program Files(x86)\ Program \'

有帮助吗?

解决方案

在MSBuild 4.0中,最简单的方法如下:

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

即使脚本被<Import>编辑到另一个脚本中,此方法仍然有效;路径相对于包含上述代码的文件。

(从 Aaron的回答以及赛义德的回答


在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\".
如果你问我,有点啰嗦,但它确实有效。这将相对于<!> quot; original <!> quot;项目文件,因此如果放在一个得到<=> ed的文件中,这将不是相对于该文件。


在MSBuild 2.0 中,有一种方法无法解析<!>“; .. <!>”。然而它的行为就像一条绝对路径:

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

$(MSBuildProjectDirectory)保留property始终是包含此引用的脚本的目录。

这也与<!>“原始<!>”相关;项目文件,因此如果放在一个得到<=> ed的文件中,这将不是相对于该文件。

其他提示

MSBuild 4.0添加了属性功能,允许您调用静态某些.net系统dll中的函数。关于Property Functions的一个非常好的事情是它们将评估目标的一面。

要评估完整路径,您可以使用系统。 IO.Path.GetFullPath 在定义如下属性时:

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

语法有点难看但非常强大。

Wayne是正确的,众所周知的元数据不适用于属性 - 仅适用于项目。使用<!>“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\'

(该脚本是从我的Documents文件夹运行的,所以.. \ Desktop是到达我桌面的正确相对路径。)

在您的情况下,请替换<!>“; .. \ Desktop <!>”; with <!> quot; ...... \ Public \ Server <!> quot;在Source_Dir项目中,您应该全部设置。

如果您需要将属性转换为项目,您有两个选项。使用msbuild 2,您可以使用 CreateItem 任务

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

使用MSBuild 3.5,您可以在任务

中包含ItemGroup
  <Target Name='Build'>
    <ItemGroup>
      <SRCDIR2 Include='$(Source_Dir)' />
    </ItemGroup>
    <Message Text="%(SRCDIR2.FullPath)" />
    <Message Text="%(SRCDIR.FullPath)" />
  </Target>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top