How can I get MSBUILD to evaluate and print the full path when given a relative path?

Eric Schoonover picture Eric Schoonover · Oct 7, 2008 · Viewed 34.6k times · Source

How can I get MSBuild to evaluate and print in a <Message /> task an absolute path given a relative path?

Property Group

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

Task

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

Output

Copying '' to 'c:\Program Files (x86)\Program\'

Answer

Roman Starkov picture Roman Starkov · Aug 9, 2009

In MSBuild 4.0, the easiest way is the following:

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

This method works even if the script is <Import>ed into another script; the path is relative to the file containing the above code.

(consolidated from Aaron's answer as well as the last part of Sayed's answer)


In MSBuild 3.5, you can use the ConvertToAbsolutePath task:

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

Relevant output:

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

A little long-winded if you ask me, but it works. This will be relative to the "original" project file, so if placed inside a file that gets <Import>ed, this won't be relative to that file.


In MSBuild 2.0, there is an approach which doesn't resolve "..". It does however behave just like an absolute path:

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

The $(MSBuildProjectDirectory) reserved property is always the directory of the script that contains this reference.

This will also be relative to the "original" project file, so if placed inside a file that gets <Import>ed, this won't be relative to that file.