重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
directory-build-organization by dotnet/skills
npx skills add https://github.com/dotnet/skills --skill directory-build-organization理解使用哪个文件至关重要。它们在评估过程中导入时机不同:
评估顺序:
Directory.Build.props → SDK .props → YourProject.csproj → SDK .targets → Directory.Build.targets
在 .props 中放置 | 在 .targets 中放置 |
|---|---|
| 设置属性默认值 | 自定义构建目标 |
| 通用项定义 | 后期绑定的属性覆盖 |
| 项目可以覆盖的属性 | 构建后步骤 |
| 程序集/包元数据 | 基于最终值的条件逻辑 |
| 分析器 PackageReferences | 依赖于 SDK 定义属性的目标 |
经验法则: 属性和项放在 中。自定义目标和后期绑定逻辑放在 中。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
.props.targets因为 .props 在项目文件之前导入,项目可以覆盖其中设置的任何值。因为 .targets 在所有内容之后导入,它具有最终决定权——但项目无法覆盖 .targets 中的值。
在 .props 文件中基于 $(TargetFramework) 的属性条件对于单目标项目会静默失败 —— 在 .props 评估期间该属性为空。应将 TFM 条件属性移至 .targets。ItemGroup 和 Target 条件不受影响。
完整解释请参阅 targetframework-props-pitfall.md。
适合放置的内容:语言设置、程序集/包元数据、构建警告、代码分析、通用分析器。
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<Company>Contoso</Company>
<Authors>Contoso Engineering</Authors>
</PropertyGroup>
</Project>
请勿放置在此处: 项目特定的 TFM、项目特定的 PackageReferences、目标/构建逻辑,或依赖于 SDK 定义值的属性(在 .props 评估期间不可用)。
适合放置的内容:自定义构建目标、后期绑定的属性覆盖(依赖于 SDK 属性的值)、构建后验证。
<Project>
<Target Name="ValidateProjectSettings" BeforeTargets="Build">
<Error Text="所有库必须面向 netstandard2.0 或更高版本"
Condition="'$(OutputType)' == 'Library' AND '$(TargetFramework)' == 'net472'" />
</Target>
<PropertyGroup>
<!-- DocumentationFile 依赖于 OutputPath,它由 SDK 设置 -->
<DocumentationFile Condition="'$(IsPackable)' == 'true'">$(OutputPath)$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
</Project>
集中式包管理为所有 NuGet 包版本提供了单一事实来源。详情请参阅 https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management。
在仓库根目录的 Directory.Packages.props 中启用 CPM:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<!-- GlobalPackageReference 应用于所有项目 —— 非常适合分析器 -->
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" />
</ItemGroup>
</Project>
包含应用于目录树下所有构建的默认 MSBuild CLI 参数。
Directory.Build.rsp 示例:
/maxcpucount
/nodeReuse:false
/consoleLoggerParameters:Summary;ForceNoAlign
/warnAsMessage:MSB3277
msbuild 和 dotnet CLI 配合使用MSBuild 只会自动导入从项目目录向上查找时找到的第一个 Directory.Build.props(或 .targets)。要链接多个级别,请在内部文件的顶部显式导入父文件。完整文件示例请参阅 multi-level-examples。
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"
Condition="Exists('$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))')" />
<!-- 内部级别的覆盖放在这里 -->
</Project>
示例布局:
repo/
Directory.Build.props ← 仓库范围(语言版本、公司信息、分析器)
Directory.Build.targets ← 仓库范围目标
Directory.Packages.props ← 集中式包版本
src/
Directory.Build.props ← 源代码特定(导入仓库级别,设置 IsPackable=true)
test/
Directory.Build.props ← 测试特定(导入仓库级别,设置 IsPackable=false,添加测试包)
在 Directory.Build.props 中设置 <ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>,以自动在单个 artifacts/ 文件夹下生成按项目名称分隔的 bin/、obj/ 和 publish/ 目录,默认避免 bin/obj 冲突。目录布局和其他模式(按项目类型的条件设置、打包后验证)请参阅 common-patterns。
.csproj 文件 —— 记录解决方案中每个 <PropertyGroup>、<ItemGroup> 和自定义 <Target>。注意哪些设置重复,哪些是项目特定的。Directory.Build.props —— 将共享的属性默认值(LangVersion、Nullable、TreatWarningsAsErrors、元数据)移至此文件。这些在项目文件之前导入,因此项目可以覆盖它们。Directory.Build.targets —— 将自定义构建目标、构建后验证以及任何依赖于 SDK 定义值的属性(例如,单目标项目的 OutputPath、TargetFramework)移至此文件。这些在 SDK 之后导入,因此所有属性都可用。Directory.Packages.props —— 启用集中式包管理(ManagePackageVersionsCentrally),列出所有 PackageVersion 条目,并从 .csproj 文件中的 PackageReference 项中移除 Version=。src/ 和 test/ 文件夹创建具有不同设置的内部 Directory.Build.props 文件。使用 GetPathOfFileAbove 链接到父级。.csproj 文件 —— 移除所有已集中化的属性、版本属性和重复的目标。每个项目应仅包含其特有的内容。dotnet restore && dotnet build 并验证没有回归。如果需要,使用 dotnet msbuild -pp:output.xml 检查最终合并视图。| 问题 | 原因 | 解决方法 |
|---|---|---|
Directory.Build.props 未被识别 | 文件名大小写错误(Linux/macOS 上需要完全匹配) | 验证确切的大小写:Directory.Build.props(大写 D, B) |
来自 .props 的属性被项目忽略 | 项目在导入后设置了相同的属性 | 将属性移至 Directory.Build.targets,以便在项目之后设置 |
| 多级导入不起作用 | 内部文件中缺少 GetPathOfFileAbove 导入 | 在内部文件顶部添加 <Import> 元素(参见多级部分) |
在 .props 中使用 SDK 值的属性为空 | 在 .props 评估期间 SDK 属性尚未定义 | 移至在 SDK 之后导入的 .targets |
Directory.Packages.props 未找到 | 文件不在仓库根目录或名称不准确 | 必须命名为 Directory.Packages.props 并位于项目目录或其上方 |
在 .props 中基于 $(TargetFramework) 的属性条件不匹配 | 在 .props 评估期间,单目标项目的 TargetFramework 尚未设置 | 将属性移至 .targets,或改用 ItemGroup/Target 条件(它们后期评估) |
诊断: 使用预处理的项目输出来查看所有导入和最终属性值:
dotnet msbuild -pp:output.xml MyProject.csproj
这将内联展开所有导入,以便您可以准确查看每个属性的设置位置以及最终评估值是什么。
每周安装量
61
仓库
GitHub 星标数
725
首次出现
2026年3月10日
安全审计
安装于
github-copilot59
opencode58
gemini-cli57
kimi-cli57
codex57
amp57
Understanding which file to use is critical. They differ in when they are imported during evaluation:
Evaluation order:
Directory.Build.props → SDK .props → YourProject.csproj → SDK .targets → Directory.Build.targets
Use .props for | Use .targets for |
|---|---|
| Setting property defaults | Custom build targets |
| Common item definitions | Late-bound property overrides |
| Properties projects can override | Post-build steps |
| Assembly/package metadata | Conditional logic on final values |
| Analyzer PackageReferences | Targets that depend on SDK-defined properties |
Rule of thumb: Properties and items go in .props. Custom targets and late-bound logic go in .targets.
Because .props is imported before the project file, the project can override any value set there. Because .targets is imported after everything, it gets the final say—but projects cannot override .targets values.
Property conditions on$(TargetFramework) in .props files silently fail for single-targeting projects — the property is empty during .props evaluation. Move TFM-conditional properties to .targets instead. ItemGroup and Target conditions are not affected.
See targetframework-props-pitfall.md for the full explanation.
Good candidates: language settings, assembly/package metadata, build warnings, code analysis, common analyzers.
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<Company>Contoso</Company>
<Authors>Contoso Engineering</Authors>
</PropertyGroup>
</Project>
Do NOT put here: project-specific TFMs, project-specific PackageReferences, targets/build logic, or properties depending on SDK-defined values (not available during .props evaluation).
Good candidates: custom build targets, late-bound property overrides (values depending on SDK properties), post-build validation.
<Project>
<Target Name="ValidateProjectSettings" BeforeTargets="Build">
<Error Text="All libraries must target netstandard2.0 or higher"
Condition="'$(OutputType)' == 'Library' AND '$(TargetFramework)' == 'net472'" />
</Target>
<PropertyGroup>
<!-- DocumentationFile depends on OutputPath, which is set by the SDK -->
<DocumentationFile Condition="'$(IsPackable)' == 'true'">$(OutputPath)$(AssemblyName).xml</DocumentationFile>
</PropertyGroup>
</Project>
Central Package Management (CPM) provides a single source of truth for all NuGet package versions. See https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management for details.
Enable CPM inDirectory.Packages.props at the repo root:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
</ItemGroup>
<ItemGroup>
<!-- GlobalPackageReference applies to ALL projects — great for analyzers -->
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" />
</ItemGroup>
</Project>
Contains default MSBuild CLI arguments applied to all builds under the directory tree.
ExampleDirectory.Build.rsp:
/maxcpucount
/nodeReuse:false
/consoleLoggerParameters:Summary;ForceNoAlign
/warnAsMessage:MSB3277
msbuild and dotnet CLI in modern .NET versionsMSBuild only auto-imports the first Directory.Build.props (or .targets) it finds walking up from the project directory. To chain multiple levels, explicitly import the parent at the top of the inner file. See multi-level-examples for full file examples.
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"
Condition="Exists('$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))')" />
<!-- Inner-level overrides go here -->
</Project>
Example layout:
repo/
Directory.Build.props ← repo-wide (lang version, company info, analyzers)
Directory.Build.targets ← repo-wide targets
Directory.Packages.props ← central package versions
src/
Directory.Build.props ← src-specific (imports repo-level, sets IsPackable=true)
test/
Directory.Build.props ← test-specific (imports repo-level, sets IsPackable=false, adds test packages)
Set <ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath> in Directory.Build.props to automatically produce project-name-separated bin/, obj/, and publish/ directories under a single artifacts/ folder, avoiding bin/obj clashes by default. See common-patterns for the directory layout and additional patterns (conditional settings by project type, post-pack validation).
.csproj files — Catalog every <PropertyGroup>, <ItemGroup>, and custom <Target> across the solution. Note which settings repeat and which are project-specific.Directory.Build.props — Move shared property defaults (LangVersion, Nullable, TreatWarningsAsErrors, metadata) here. These are imported before the project file so projects can override them.Directory.Build.targets — Move custom build targets, post-build validation, and any properties that depend on SDK-defined values (e.g., OutputPath, TargetFramework for single-targeting projects) here. These are imported after the SDK so all properties are available.| Problem | Cause | Fix |
|---|---|---|
Directory.Build.props isn't picked up | File name casing wrong (exact match required on Linux/macOS) | Verify exact casing: Directory.Build.props (capital D, B) |
Properties from .props are ignored by projects | Project sets the same property after the import | Move the property to Directory.Build.targets to set it after the project |
| Multi-level import doesn't work | Missing GetPathOfFileAbove import in inner file | Add the <Import> element at the top of the inner file (see Multi-level section) |
Diagnosis: Use the preprocessed project output to see all imports and final property values:
dotnet msbuild -pp:output.xml MyProject.csproj
This expands all imports inline so you can see exactly where each property is set and what the final evaluated value is.
Weekly Installs
61
Repository
GitHub Stars
725
First Seen
Mar 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
github-copilot59
opencode58
gemini-cli57
kimi-cli57
codex57
amp57
minimax-docx:基于 OpenXML SDK 的 DOCX 文档自动化创建与编辑工具
1,500 周安装
review-requesting-code-review - 代码审查请求GitHub技能,提升团队协作与代码质量
1 周安装
plan-writing技能:AI代码规划与配置管理工具,提升开发效率
1 周安装
plan-tdd 测试驱动开发规划工具 - 提升代码质量与开发效率
1 周安装
plan-execution代码执行技能 - 提升开发效率的AI编程工具,支持多编辑器集成
1 周安装
notes-knowledge-graph:基于Codex的笔记知识图谱技能,提升信息组织与检索效率
1 周安装
iOS XCTrace 参考配置 - 开发者工具与调试技能
1 周安装
Directory.Packages.propsManagePackageVersionsCentrallyPackageVersionVersion=PackageReference.csprojDirectory.Build.props files for src/ and test/ folders with distinct settings. Use GetPathOfFileAbove to chain to the parent..csproj files — Remove all centralized properties, version attributes, and duplicated targets. Each project should only contain what is unique to it.dotnet restore && dotnet build and verify no regressions. Use dotnet msbuild -pp:output.xml to inspect the final merged view if needed.Properties using SDK values are empty in .props | SDK properties aren't defined yet during .props evaluation | Move to .targets which is imported after the SDK |
Directory.Packages.props not found | File not at repo root or not named exactly | Must be named Directory.Packages.props and at or above the project directory |
Property condition on $(TargetFramework) doesn't match in .props | TargetFramework isn't set yet for single-targeting projects during .props evaluation | Move property to .targets, or use ItemGroup/Target conditions instead (which evaluate late) |