查找MSBuildProjectDirectory的父目录

12

MSBuild 3.5

我有以下的项目结构:

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

到目前为止,我一直在使用以下属性来找出项目根文件夹:

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

一切都很顺利,直到我尝试使用一个依赖于此路径的复制任务时。它没有正确地解析。我最终得到了像这样不合法的东西:

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

基本上,我需要获取(MSBuildProjectDirectory)的父级的完整路径。

3个回答

16

项目元数据是你的好伙伴!

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

看起来很不错!你知道我怎么用这个来创建一个带路径的变量吗?例如:<CodeFolder>%(MSBuildParentDirectory.Fullpath)</CodeFolder>但显然这样行不通... - B Z
属性在目标执行之前进行评估,您必须使用CreateProperty任务(请参见我的编辑)。 - Julien Hoarau
好的,你是说我需要使用创建属性任务吗?我问这个问题的原因是因为我目前有大约5个需要这个路径的属性。例如:CodeFolder、DBFolder、DeployFolder等等... - B Z
如果你绝对需要5个属性,是的,这就是我的意思。 - Julien Hoarau

3

现今在使用 MSBuild 4.0 及以上版本时,您不再需要使用 CreateItem 或 CreateProperty 任务。您所需的功能可以通过 MSBuild 属性函数轻松实现:

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

如果您只想读取父目录的文件夹名称,可以将上述语句与 GetFileName 属性函数结合使用:

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

这个答案可能有点啰嗦,但比其他答案好得多,因为它可以在目标外运行并分配给属性。

1

如果有人像我一样对此还感兴趣,以下是我在2022年的做法 ^_^

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

我使用这种技术来自动命名复杂解决方案中的程序集和默认命名空间。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接