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

And*_*kov 7 msbuild visual-studio

我有这样的情况:

我的项目目录中有一个 .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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

所以以上都有这个文件夹结构:

Solution directory
  Directory.Build.props
  Project Directory
    Project.mproj
    Subdir
      add.targets
Run Code Online (Sandbox Code Playgroud)

准备好上述所有内容后,我预计 aProperty 将在导入之前启动,并且 add.targets 的导入将顺利进行。但我收到错误消息,指出未找到导入的项目,并且我在错误消息中看到 MSBuild 尝试从项目目录导入,而不是从子目录 Subdir 导入。

如果我取消注释这一行:

<Import Project="..\Directory.Build.props" />
Run Code Online (Sandbox Code Playgroud)

一切正常。

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

在 Visual Studio 中工作时,有什么方法可以强制 MSBuild 在任何其他导入之前隐式导入 Directory.Build.props ?

Lan*_*SFT 6

“在 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> 
Run Code Online (Sandbox Code Playgroud)

每次创建新的C#或VB项目时,<Project>节点内的最上面一行是Import project="Microsoft.Common.props",我们可以从该文档中找到这句话:

当 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默认情况下始终是项目节点的第一行,因此 Directory.Build.Targets 总是在 Microsoft.Build.Targets 之后隐式导入。 Common.props 和其他之前。

注意:此功能仅支持 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" />