How can I get the current directory in an MSBuild script?
Asked Answered
A

3

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.

Azobenzene answered 21/1, 2010 at 17:16 Comment(1)
Will your temp folder always be a sub folder of the location from which this script is to be run?Hoarse
S
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.

Sheepshank answered 21/1, 2010 at 18:28 Comment(1)
+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 supportedHarbird
B
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)'" />
Beitnes answered 21/1, 2010 at 19:39 Comment(6)
Why use dir . instead of cd?Abbotson
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 '.'"....Beitnes
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 ;-).Abbotson
dir '.' doesn't report an error for me. It lists the directory and files/folders. I don't know about xbuild.Beitnes
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…Abbotson
'dir .' printed my root (c:). Strange. 'cd' printed out dir of exec'ing batch file.Schnitzler
C
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.

Cullender answered 21/1, 2010 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.