自动导入工程项目属性,Directory.Build.props 和 Directory.Build.targets
在 MSBuild 15 的一个新的功能就是让开发者可以自己定义项目信息放在一个文件,这个文件会在 Microsoft.Common.props 引用,而且会在csproj项目文件所在的文件夹开始寻找,只要找到存在Directory.Build.props文件就会自动导入里面的内容。除了定义Directory.Build.props之外,还可以定义 Directory.Build.targets 文件,不同的只是这个文件是在 Microsoft.Common.targets使用。
Directory.Build.props 是 MSBuild 提供的一个**“魔法文件”** ——
只要把它放在 repo 的任意一级目录下,MSBuild 会自动把它注入到该目录下(及所有子目录)的每一个 .csproj 项目文件里,无需任何 <Import>。
放置位置 影响范围
/Directory.Build.props 整个仓库的所有项目
/src/Directory.Build.props /src 及其所有子目录里的项目
/tests/Directory.Build.props /tests 及其所有子目录里的项目
典型用途
统一 TargetFramework、Nullable、ImplicitUsings
统一 Company、Copyright、VersionPrefix
统一 PackageReference(如日志、JSON、测试框架)
统一 CodeAnalysis 规则集、强命名、签名文件路径
最小可运行示例
文件: /Directory.Build.props
<Project> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <Company>MySoft</Company> <VersionPrefix>1.2.0</VersionPrefix> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" /> </ItemGroup> </Project>
之后任何 .csproj 都会自动继承上述设置,不需要写一行 <Import> 。
⚠️ 注意点
文件名必须一字不差:Directory.Build.props,大小写敏感(Linux/macOS)。
如果子目录里也有同名文件,离项目最近的那一份获胜(可覆盖上级)。
与手动 <Import> 的 .props 不冲突,但 Directory.Build.props 先执行,后执行 .csproj 本身的内容,因此 .csproj 里的值可以覆盖它。
还有一个对应文件:Directory.Build.targets,作用相同,但在 .csproj 之后执行,适合做 Target 定义。
下面给出一个可直接放到仓库根目录的 Directory.Build.targets 示例,演示几个典型用法:
编译后把 README.md 拷到输出目录
统一给所有 PackageReference 打补丁,强制把 PrivateAssets="all" 加到 Newtonsoft.Json 上
在 AfterBuild 里打印一条“构建完成”的提示
文件:/Directory.Build.targets
<Project> <!-- 1. 把 README.md 复制到输出目录 --> <Target Name="CopyReadme" AfterTargets="Build"> <ItemGroup> <ReadmeFile Include="$(MSBuildThisFileDirectory)README.md" /> </ItemGroup> <Copy SourceFiles="@(ReadmeFile)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" /> </Target> <!-- 2. 强制给 Newtonsoft.Json 加上 PrivateAssets="all" --> <Target Name="PatchNewtonsoft" BeforeTargets="CollectPackageReferences"> <ItemGroup> <PackageReference Condition=" '%(PackageReference.Identity)' == 'Newtonsoft.Json' "> <PrivateAssets>all</PrivateAssets> </PackageReference> </ItemGroup> </Target> <!-- 3. 构建完成后打印提示 --> <Target Name="SayDone" AfterTargets="Build"> <Message Text=" Build finished: $(MSBuildProjectName) -> $(TargetPath)" Importance="high" /> </Target> </Project>
使用方式
把文件保存为 /Directory.Build.targets(或任意子目录,作用范围同 Directory.Build.props)。
无需任何 <Import>,下次 dotnet build 会自动生效。

浙公网安备 33010602011771号