B Z
B Z

Reputation: 9463

Find MSBuildProjectDirectory Parent Directory

MSBuild 3.5

I have the following project structure:

trunk/MainSolution.sln
trunk/Build/MyBuild.Proj
trunk/Library/...
trunk/etc...

So far, I've been using the following property to find out the project root folder:

<RootFolder>$(MSBuildProjectDirectory)\..\</RootFolder>

Everything was working great, until I tried using a copy task that relied on this path. It is not resolving correctly. I basically end up getting something like this which is not valid:

C:\Projects\MyProject\Trunk\Build\..\CodeAnalysis\myfile.xml

So basically, I need to get the full path for (MSBuildProjectDirectory)'s Parent.

Upvotes: 12

Views: 11293

Answers (3)

Wahid Bitar
Wahid Bitar

Reputation: 14100

In case someone like me is still interested in this, here is how I did it in 2022 ^_^

<PropertyGroup> 
    <ParentFolderPath>$([System.IO.Directory]::GetParent($(MSBuildProjectDirectory)))</ParentFolderPath>
    <ParentFolder>$([System.IO.Path]::GetFileName($(ParentFolderPath)))</ParentFolder>
...
</PropertyGroup> 

I'm using this technique to auto-name the assemblies and default namespaces in the complex solutions.

<AssemblyName>$(ParentFolder).$(MSBuildProjectName)</AssemblyName>
<RootNamespace>$(ParentFolder).$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>

Upvotes: 2

Viktor Hofer
Viktor Hofer

Reputation: 380

Nowadays with MSBuild 4.0 and above you don't want to use CreateItem or CreateProperty tasks anymore. What you are asking for can be solved easily with msbuild property functions:

<!-- Prints the parent directory's full path. -->
$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..'))

If you just want to read the parent directory's folder name you can combine the above statement with the GetFileName property function:

$([System.IO.Path]::GetFileName('$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..'))'))

A bit verbose but much better than the other answer as this works outside of targets and can be assigned to a property.

Upvotes: 3

Julien Hoarau
Julien Hoarau

Reputation: 50000

Item metadata is your friend!

<Target Name="GetMSBuildProjectParentDirectory">
  <!-- First you create the MSBuildProject Parent directory Item -->
  <CreateItem Include="$(MSBuildProjectDirectory)\..\">
    <Output ItemName="MSBuildProjectParentDirectory" TaskParameter="Include"/>
  </CreateItem>

  <!-- You can now retrieve its fullpath using Fullpath metadata -->
  <Message Text="%(MSBuildProjectParentDirectory.Fullpath)"/>

  <!-- Create a property based on parent fullpath-->
  <CreateProperty Value="%(MSBuildProjectParentDirectory.Fullpath)">
    <Output PropertyName="CodeFolder" TaskParameter="Value"/>
  </CreateProperty>
</Target>

Upvotes: 16

Related Questions