如何从Visual Studio的项目文件导入中使用Directory.Build.props中的属性

时间:2019-03-18 00:10:30

标签: visual-studio msbuild

我有这种情况:

我在项目目录中有一个.proj文件:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Compile Include="PQExtensionTest.pq">
      <SubType>Code</SubType>
    </Compile>
    <Content Include="PQExtensionTest.query.pq">
      <SubType>Code</SubType>
    </Content>
  </ItemGroup>
  <!-- <Import Project="..\Directory.Build.props" /> -->
  <Import Project="$(aProperty)add.targets" />
</Project>

在解决方案目录中(项目目录中的.. \),我有Directory.Build.props文件:

<Project DefaultTargets="BuildExtension" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <aProperty>$(MSBuildProjectDirectory)/Subdir/</aProperty>
  </PropertyGroup>
</Project>

在项目目录中,我有子目录“ Subdir”,其中有文件add.targets,其中包含我需要的所有目标(由于与问题无关,因此此处不包含它)。

因此,以上所有内容均具有以下文件夹结构:

Solution directory
  Directory.Build.props
  Project Directory
    Project.mproj
    Subdir
      add.targets

准备以上所有内容,我希望aProperty将在导入之前启动,并且add.targets的导入将毫无问题地发生。但是我收到未找到导入项目的错误,并且在错误消息中看到MSBuild尝试从项目目录而不是从子目录Subdir导入。

如果我取消注释该行:

<Import Project="..\Directory.Build.props" />

一切正常。

对我而言,这种行为的唯一合理解释是,在导入时aProperty为空,因为显式导入发生在隐式导入之前。

在Visual Studio中工作时,是否有任何方法可以强制MSBuild在其他任何导入之前不明确地导入Directory.Build.props?

2 个答案:

答案 0 :(得分:1)

“在Visual Studio中”

  

对于C#和VB语言项目,我们不需要导入   手动执行Directory.Build.props或将其强制执行。

在VS中创建新项目(C#或VB)时,打开其proj文件,我们会发现格式如下:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    ...
  </PropertyGroup>
  <ItemGroup>
    ...
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> 

每次创建新的C#或VB项目时,<Project>节点内的第一行都是Import project="Microsoft.Common.props",我们可以从this document中找到该句子:

MSBuild运行时,Microsoft.Common.props在目录结构中搜索Directory.Build.props文件(和Microsoft.Common.targets looks for Directory.Build.targets)。 如果找到一个,则会导入该属性。

因此在Visual Studio中,我们无需在其他导入之前强制使用它。它总是在import Microsoft.Common.props之后调用,并且由于import Microsoft.Common.props始终默认为项目节点的第一行,因此目录始终在Microsoft.Common.props之后以及其他之前隐式导入.Build.Targets。

注意:此功能仅支持C#和VB,因为只有这两种项目会在proj文件中导入Microsoft.Common.Props。

  

对于其他类型的项目,例如.mproj或   .vcxproj(C ++),不支持此功能(Directory.Build.props)   

因此Directory.Build.Targets或.props与任何自定义.props相同。 Directory.Build.Targets和anyName.props之间没有区别。

通过这种方式,要读取其中的值,我们必须使用import project来手动调用它。 这就是为什么在取消注释该行之前构建无法成功的原因<Import Project="..\Directory.Build.props" />

答案 1 :(得分:0)

从嵌套文件夹结构从“ Directory.Build.props”文件导入属性的方法如下:

引用:https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019

请注意: 1.这些属性文件定义可从MSBuild工具15.0版开始使用 2.您需要知道此导入的位置:在文件的开头或文件的结尾。通常,最好将其放置在末尾,因为嵌套属性对父属性是可见的。

相关问题