74

In my MSBuild script I need to pass the full directory as a parameter. How can I get it?

Example: I am running the script from C:\dev, and I want a relative path, temp, so I am after C:\dev\temp.

Note: I don't know from which folder the script will be run.

1
  • Will your temp folder always be a sub folder of the location from which this script is to be run?
    – brunch
    Commented Jan 21, 2010 at 17:21

3 Answers 3

110

Igor is pretty close. MSBuildProjectDirectory is the property that will give you the full path to the project file which was invoked on the command line. So if you have the following scripts:

  • C:\temp\MyProj.proj
  • C:\shared\shared.targets

And MyProj.proj imports shared.targets and this is the one passed to msbuild.exe then the value for MSBuildProjectDirectory will always be C:\temp even if you are referencing that inside of shared.targets. If your shared.targets requires path knowledge then those should be declared in known properties. For example C# project files define the value for OutputPath and the shared file Microsoft.Common.targets uses that property.

Edit: MSBuild 4

If you are using MSBuild 4, you can also use these properties for this type of value.

  • MSBuildThisFile
  • MSBuildThisFileDirectory
  • MSBuildThisFileDirectoryNoRoot
  • MSBuildThisFileExtension
  • MSBuildThisFileFullPath
  • MSBuildThisFileName

See http://sedodream.com/2010/03/11/MSBuild40ReservedProperties.aspx.

1
  • 4
    +1 note that those new MSBuild 4 reserved properties are not listed in the list of macros in Visual Studio 2010 edit dialog even though they are supported
    – Amro
    Commented Jun 19, 2013 at 19:51
61

Here are three targets that are helpful.

WhereAmI is the one I use when trying to figure out my current directory of course.

The others are informative as well (some are beyond the scope of the question).

<Target Name="WhereAmI">
    <Message Text=" Here I Am  " />
    <Exec Command="dir ." />
    <Message Text=" " />
</Target>



<Target Name="ShowReservedProperties" AfterTargets="BeforeBuild">
    <Message Text=" MSBuildProjectDirectory  = $(MSBuildProjectDirectory)" Importance="high" />
    <Message Text=" MSBuildProjectFile  = $(MSBuildProjectFile)" Importance="high" />
    <Message Text=" MSBuildProjectExtension  = $(MSBuildProjectExtension)" Importance="high" />
    <Message Text=" MSBuildProjectFullPath  = $(MSBuildProjectFullPath)" Importance="high" />
    <Message Text=" MSBuildProjectName  = $(MSBuildProjectName)" Importance="high" />
    <Message Text=" MSBuildBinPath  = $(MSBuildBinPath)" Importance="high" />
    <Message Text=" MSBuildProjectDefaultTargets  = $(MSBuildProjectDefaultTargets)" Importance="high" />
    <Message Text=" MSBuildExtensionsPath  = $(MSBuildExtensionsPath)" Importance="high" />
    <Message Text=" MSBuildStartupDirectory  = $(MSBuildStartupDirectory)" Importance="high"/>
</Target>


  <Target Name="ShowOtherProperties">
    <Message Text="  " />
    <Message Text="  " />
    <Message Text=" Environment (SET) Variables*       " />
    <Message Text=" ---------------------------        " />
    <Message Text=" COMPUTERNAME = *$(COMPUTERNAME)*   " />
    <Message Text=" USERDNSDOMAIN = *$(USERDNSDOMAIN)* " />
    <Message Text=" USERDOMAIN = *$(USERDOMAIN)*       " />
    <Message Text=" USERNAME = *$(USERNAME)*           " />
</Target>

If you're using an "external MSBuild file" and need to pass a filename or path to it (because external MSBuild files do not like relative files if they are not in the same directory as the calling .msbuild file)....here is a convenient (3.5 and up I believe) Task.

    <ConvertToAbsolutePath Paths="..\"> <!-- Some relative path here -->
      <Output TaskParameter="AbsolutePaths" PropertyName="MyAbsolutionPathProperty"/>
    </ConvertToAbsolutePath>
    <Message Text="'MyAbsolutionPathProperty' = '$(MyAbsolutionPathProperty)'" />
6
  • Why use dir . instead of cd?
    – binki
    Commented Apr 10, 2014 at 21:04
  • dir '.' reports the directory. cd is change_directory and will move me out of the folder. I guess you could do "cd ." but I don't see what that gives you over "dir '.'".... Commented Apr 10, 2014 at 21:28
  • 1
    dir . prints out so much more than the working directory. dir '.' prints out an error message in addition to the CWD because no such file exists. CD with no arguments displays the current path without altering it. I am assuming we’re talking about cmd here, not what would happen if you ran your script through xbuild ;-).
    – binki
    Commented Apr 10, 2014 at 21:34
  • dir '.' doesn't report an error for me. It lists the directory and files/folders. I don't know about xbuild. Commented Apr 10, 2014 at 21:42
  • imgur.com/fTudXkB , just sayin’ :-p. Works without the quotes but displays the directory listing instead of just your current directory (which is exactly and only what CD (with no arguments) prints out). Sorry, I’m nitpicking. But, for example, in AppData\Local\Temp, the output of dir . is quite unhelpful if you just want to know where you are because there are so many files in there…
    – binki
    Commented Apr 11, 2014 at 5:47
13

MSBuild has reserved property called MSBuildProjectDirectory, which is to the absolute path of the directory where you project or script file is located, C:\Dev in your case. Therefore "$(MSBuildProjectDirectory)\temp" is exactly what you're looking for.

Not the answer you're looking for? Browse other questions tagged or ask your own question.