check-bin-obj-clash
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDetecting OutputPath and IntermediateOutputPath Clashes
检测 OutputPath 和 IntermediateOutputPath 冲突
Overview
概述
This skill helps identify when multiple MSBuild project evaluations share the same or . This is a common source of build failures including:
OutputPathIntermediateOutputPath- File access conflicts during parallel builds
- Missing or overwritten output files
- Intermittent build failures
- "File in use" errors
- NuGet restore errors like - this strongly indicates multiple projects share the same
Cannot create a file when that file already existswhereIntermediateOutputPathis writtenproject.assets.json
Clashes can occur between:
- Different projects sharing the same output directory
- Multi-targeting builds (e.g., ) where the path doesn't include the target framework
TargetFrameworks=net8.0;net9.0 - Multiple solution builds where the same project is built from different solutions in a single build
Note: Project instances with should be ignored when analyzing clashes - these are P2P reference resolution builds that only query metadata (via ) and do not actually write to output directories.
BuildProjectReferences=falseGetTargetPath本技能可帮助识别多个 MSBuild 项目评估共享同一个 或 的问题,这是构建失败的常见诱因,包括:
OutputPathIntermediateOutputPath- 并行构建期间的文件访问冲突
- 输出文件丢失或被覆盖
- 偶现的构建失败
- 「文件被占用」错误
- 类似 的 NuGet 还原错误——这强烈说明多个项目共享了同一个写入
Cannot create a file when that file already exists的project.assets.jsonIntermediateOutputPath
冲突可能发生在以下场景:
- 不同项目共享同一个输出目录
- 多目标构建(例如 )的路径不包含目标框架标识
TargetFrameworks=net8.0;net9.0 - 多解决方案构建中,同一个项目在单次构建流程中被不同的解决方案触发构建
注意: 分析冲突时应忽略的项目实例——这些是P2P引用解析构建,仅用于查询元数据(通过),不会实际写入输出目录。
BuildProjectReferences=falseGetTargetPathWhen to Use This Skill
何时使用本技能
Invoke this skill immediately when you see:
- during NuGet restore
Cannot create a file when that file already exists The process cannot access the file because it is being used by another process- Intermittent build failures that succeed on retry
- Missing output files or unexpected overwriting
当遇到以下情况时请立即调用本技能:
- NuGet 还原过程中报
Cannot create a file when that file already exists - 报
The process cannot access the file because it is being used by another process - 重试后可成功的偶现构建失败
- 输出文件丢失或出现非预期覆盖
Step 1: Generate a Binary Log
步骤1:生成二进制日志
Use the skill to generate a binary log with the correct naming convention.
binlog-generation使用技能,按照规范命名生成二进制日志。
binlog-generationStep 2: Replay the Binary Log to Text
步骤2:将二进制日志重放为文本格式
bash
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.logbash
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.logStep 3: List All Projects
步骤3:列出所有参与构建的项目
bash
grep -i 'done building project\|Building project' full.log | grep -oP '"[^"]+\.csproj"' | sort -uThis lists all project files that participated in the build.
bash
grep -i 'done building project\|Building project' full.log | grep -oP '"[^"]+\.csproj"' | sort -u该命令会列出所有参与本次构建的项目文件。
Step 4: Check for Multiple Evaluations per Project
步骤4:检查每个项目的评估次数
Multiple evaluations for the same project indicate multi-targeting or multiple build configurations:
bash
undefined同一个项目出现多次评估说明存在多目标构建或多构建配置:
bash
undefinedCount how many times each project was evaluated
统计每个项目的评估次数
grep -c 'Evaluation started' full.log
grep 'Evaluation started.*.csproj' full.log
undefinedgrep -c 'Evaluation started' full.log
grep 'Evaluation started.*.csproj' full.log
undefinedStep 5: Check Global Properties for Each Evaluation
步骤5:检查每次评估的全局属性
For each project, query the build properties to understand the build configuration:
bash
undefined针对每个项目,查询构建属性以了解构建配置:
bash
undefinedSearch the diagnostic log for evaluated property values
在诊断日志中搜索评估后的属性值
grep -i 'TargetFramework|Configuration|Platform|RuntimeIdentifier' full.log | head -40
Look for properties like `TargetFramework`, `Configuration`, `Platform`, and `RuntimeIdentifier` that should differentiate output paths.
Also check **solution-related properties** to identify multi-solution builds:
- `SolutionFileName`, `SolutionName`, `SolutionPath`, `SolutionDir`, `SolutionExt` — differ when a project is built from multiple solutions
- `CurrentSolutionConfigurationContents` — the number of project entries reveals which solution an evaluation belongs to (e.g., 1 project vs ~49 projects)
Look for **extra global properties that don't affect output paths** but create distinct MSBuild project instances:
- `PublishReadyToRun` — a publish setting that doesn't change `OutputPath` or `IntermediateOutputPath`, but MSBuild treats it as a distinct project instance, preventing result caching and causing redundant target execution (e.g., `CopyFilesToOutputDirectory` running again)
- Any other global property that differs between evaluations but doesn't contribute to path differentiationgrep -i 'TargetFramework|Configuration|Platform|RuntimeIdentifier' full.log | head -40
重点查找可以区分输出路径的属性,例如`TargetFramework`、`Configuration`、`Platform`、`RuntimeIdentifier`。
同时检查**解决方案相关属性**以识别多解决方案构建:
- `SolutionFileName`、`SolutionName`、`SolutionPath`、`SolutionDir`、`SolutionExt`——当项目从多个解决方案构建时,这些属性值会不同
- `CurrentSolutionConfigurationContents`——其中的项目条目数量可以说明评估属于哪个解决方案(例如1个项目 vs 约49个项目)
查找**不会影响输出路径但会生成独立MSBuild项目实例的额外全局属性**:
- `PublishReadyToRun`——发布设置,不会修改`OutputPath`或`IntermediateOutputPath`,但MSBuild会将其识别为独立的项目实例,导致结果缓存失效、目标重复执行(例如`CopyFilesToOutputDirectory`重复运行)
- 其他不同评估之间存在差异但不会影响路径区分的全局属性Filter Out Non-Build Evaluations
过滤非构建评估
When analyzing clashes, filter evaluations based on the type of clash you're investigating:
-
For OutputPath clashes: Exclude restore-phase evaluations (whereglobal property is set). These don't write to output directories.
MSBuildRestoreSessionId -
For IntermediateOutputPath clashes: Include restore-phase evaluations, as NuGet restore writesto the intermediate output path.
project.assets.json -
Always exclude: These are P2P metadata queries, not actual builds that write files.
BuildProjectReferences=false
分析冲突时,可根据你排查的冲突类型过滤评估:
- 排查OutputPath冲突:排除还原阶段的评估(设置了全局属性的评估),这类评估不会写入输出目录。
MSBuildRestoreSessionId - 排查IntermediateOutputPath冲突:包含还原阶段的评估,因为NuGet还原会向中间输出路径写入。
project.assets.json - 始终排除的评估:这类是P2P元数据查询,不是实际会写入文件的构建流程。
BuildProjectReferences=false
Step 6: Get Output Paths for Each Project
步骤6:获取每个项目的输出路径
Query each project's output path properties:
bash
undefined查询每个项目的输出路径属性:
bash
undefinedFrom the diagnostic log - search for OutputPath assignments
从诊断日志中搜索OutputPath配置
grep -i 'OutputPath\s*=|IntermediateOutputPath\s*=|BaseOutputPath\s*=|BaseIntermediateOutputPath\s*=' full.log | head -40
grep -i 'OutputPath\s*=|IntermediateOutputPath\s*=|BaseOutputPath\s*=|BaseIntermediateOutputPath\s*=' full.log | head -40
Or query a specific project directly
或者直接查询指定项目的配置
dotnet msbuild MyProject.csproj -getProperty:OutputPath
dotnet msbuild MyProject.csproj -getProperty:IntermediateOutputPath
dotnet msbuild MyProject.csproj -getProperty:BaseOutputPath
dotnet msbuild MyProject.csproj -getProperty:BaseIntermediateOutputPath
undefineddotnet msbuild MyProject.csproj -getProperty:OutputPath
dotnet msbuild MyProject.csproj -getProperty:IntermediateOutputPath
dotnet msbuild MyProject.csproj -getProperty:BaseOutputPath
dotnet msbuild MyProject.csproj -getProperty:BaseIntermediateOutputPath
undefinedStep 7: Identify Clashes
步骤7:识别冲突
Compare the and values across all evaluations:
OutputPathIntermediateOutputPath- Normalize paths - Convert to absolute paths and normalize separators
- Group by path - Find evaluations that share the same OutputPath or IntermediateOutputPath
- Report clashes - Any group with more than one evaluation indicates a clash
对比所有评估的和值:
OutputPathIntermediateOutputPath- 路径标准化——转换为绝对路径并统一路径分隔符
- 按路径分组——找到共享同一个OutputPath或IntermediateOutputPath的评估
- 上报冲突——任何包含超过1个评估的分组都说明存在冲突
Step 8: Verify Clashes via CopyFilesToOutputDirectory (Optional)
步骤8:通过CopyFilesToOutputDirectory验证冲突(可选)
As additional evidence for OutputPath clashes, check if multiple project builds execute the target to the same path. Note that not all clashes manifest here - compilation outputs and other targets may also conflict.
CopyFilesToOutputDirectorybash
undefined作为OutputPath冲突的补充证据,可检查是否有多个项目构建向同一路径执行目标。注意不是所有冲突都会在这一步体现——编译输出和其他目标也可能出现冲突。
CopyFilesToOutputDirectorybash
undefinedSearch for CopyFilesToOutputDirectory target execution per project
搜索每个项目的CopyFilesToOutputDirectory目标执行记录
grep 'Target "CopyFilesToOutputDirectory"' full.log
grep 'Target "CopyFilesToOutputDirectory"' full.log
Look for Copy task messages showing file destinations
查找显示文件目标路径的Copy任务消息
grep 'Copying file from|SkipUnchangedFiles' full.log | head -30
Look for evidence of clashes in the messages:
- `Copying file from "..." to "..."` - Active file writes
- `Did not copy from file "..." to file "..." because the "SkipUnchangedFiles" parameter was set to "true"` - Indicates a second build attempted to write to the same location
The `SkipUnchangedFiles` skip message often masks clashes - the build succeeds but is vulnerable to race conditions in parallel builds.grep 'Copying file from|SkipUnchangedFiles' full.log | head -30
在消息中查找冲突证据:
- `Copying file from "..." to "..."`——活跃的文件写入操作
- `Did not copy from file "..." to file "..." because the "SkipUnchangedFiles" parameter was set to "true"`——说明第二次构建尝试写入同一个位置
`SkipUnchangedFiles`跳过消息通常会掩盖冲突——构建会成功,但并行构建时存在竞态条件风险。Step 9: Check CoreCompile Execution Patterns (Optional)
步骤9:检查CoreCompile执行模式(可选)
To understand which project instance did the actual compilation vs redundant work, check :
CoreCompilebash
grep 'Target "CoreCompile"' full.logCompare the durations:
- The instance with a long duration (e.g., seconds) is the primary build that did the actual compilation
CoreCompile - Instances where was skipped (duration ~0-10ms) are redundant builds — they didn't recompile but may still run other targets like
CoreCompilethat write to the same output directoryCopyFilesToOutputDirectory
This helps distinguish the "real" build from redundant instances created by extra global properties or multi-solution builds.
要区分实际执行编译的项目实例和冗余实例,可检查:
CoreCompilebash
grep 'Target "CoreCompile"' full.log对比执行时长:
- 执行时长久(例如数秒)的实例是主构建,执行了实际的编译工作
CoreCompile - 被跳过的实例(时长约0-10ms)是冗余构建——它们没有重新编译,但仍可能执行其他会写入同一输出目录的目标,例如
CoreCompileCopyFilesToOutputDirectory
这有助于区分「真实」构建和由额外全局属性、多解决方案构建生成的冗余实例。
Caveat: Multi-Solution Builds
注意:多解决方案构建
When analyzing multi-solution builds, note that the diagnostic log interleaves output from all projects. To determine which solution a project instance belongs to, search for property assignments in the diagnostic log:
SolutionFileNamebash
grep -i "SolutionFileName\|CurrentSolutionConfigurationContents" full.log | head -20分析多解决方案构建时,请注意诊断日志会交错显示所有项目的输出。要确定项目实例属于哪个解决方案,可在诊断日志中搜索属性配置:
SolutionFileNamebash
grep -i "SolutionFileName\|CurrentSolutionConfigurationContents" full.log | head -20Expected Output Structure
预期输出结构
For each evaluation, collect:
- Project file path
- Evaluation ID
- TargetFramework (if multi-targeting)
- Configuration
- OutputPath
- IntermediateOutputPath
为每个评估收集以下信息:
- 项目文件路径
- 评估ID
- TargetFramework(如果是多目标构建)
- Configuration
- OutputPath
- IntermediateOutputPath
Clash Detection Logic
冲突检测逻辑
For each unique OutputPath:
- If multiple evaluations share it → CLASH
For each unique IntermediateOutputPath:
- If multiple evaluations share it → CLASH对于每个唯一的OutputPath:
- 如果多个评估共享该路径 → 存在冲突
对于每个唯一的IntermediateOutputPath:
- 如果多个评估共享该路径 → 存在冲突Common Causes and Fixes
常见原因与修复方案
Multi-targeting without TargetFramework in path
多目标构建的路径未包含TargetFramework
Problem: Project uses but OutputPath doesn't vary by framework.
TargetFrameworksxml
<!-- BAD: Same path for all frameworks -->
<OutputPath>bin\$(Configuration)\</OutputPath>Fix: Include TargetFramework in the path:
xml
<!-- GOOD: Path varies by framework -->
<OutputPath>bin\$(Configuration)\$(TargetFramework)\</OutputPath>Or rely on SDK defaults which handle this automatically:
xml
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<AppendTargetFrameworkToIntermediateOutputPath>true</AppendTargetFrameworkToIntermediateOutputPath>问题: 项目使用了但OutputPath没有按框架区分。
TargetFrameworksxml
<!-- 错误:所有框架使用相同路径 -->
<OutputPath>bin\$(Configuration)\</OutputPath>修复: 在路径中加入TargetFramework:
xml
<!-- 正确:路径按框架区分 -->
<OutputPath>bin\$(Configuration)\$(TargetFramework)\</OutputPath>或者直接使用SDK默认配置,会自动处理该问题:
xml
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<AppendTargetFrameworkToIntermediateOutputPath>true</AppendTargetFrameworkToIntermediateOutputPath>Shared output directory across projects (CANNOT be fixed with AppendTargetFramework)
跨项目共享输出目录(无法通过AppendTargetFramework修复)
Problem: Multiple projects explicitly set the same or .
BaseOutputPathBaseIntermediateOutputPathxml
<!-- Project A - Directory.Build.props -->
<BaseOutputPath>..\SharedOutput\</BaseOutputPath>
<BaseIntermediateOutputPath>..\SharedObj\</BaseIntermediateOutputPath>
<!-- Project B - Directory.Build.props -->
<BaseOutputPath>..\SharedOutput\</BaseOutputPath>
<BaseIntermediateOutputPath>..\SharedObj\</BaseIntermediateOutputPath>IMPORTANT: Even with , this will still clash! .NET writes certain files directly to the without the TargetFramework suffix, including:
AppendTargetFrameworkToOutputPath=trueIntermediateOutputPath- (NuGet restore output)
project.assets.json - Other NuGet-related files
This causes errors like during parallel restore.
Cannot create a file when that file already existsFix: Each project MUST have a unique . Do not share intermediate output directories across projects:
BaseIntermediateOutputPathxml
<!-- Project A -->
<BaseIntermediateOutputPath>..\obj\ProjectA\</BaseIntermediateOutputPath>
<!-- Project B -->
<BaseIntermediateOutputPath>..\obj\ProjectB\</BaseIntermediateOutputPath>Or simply use the SDK defaults which place inside each project's directory.
obj问题: 多个项目显式设置了相同的或。
BaseOutputPathBaseIntermediateOutputPathxml
<!-- 项目A的Directory.Build.props -->
<BaseOutputPath>..\SharedOutput\</BaseOutputPath>
<BaseIntermediateOutputPath>..\SharedObj\</BaseIntermediateOutputPath>
<!-- 项目B的Directory.Build.props -->
<BaseOutputPath>..\SharedOutput\</BaseOutputPath>
<BaseIntermediateOutputPath>..\SharedObj\</BaseIntermediateOutputPath>重要提示: 即使设置了,仍然会出现冲突!.NET会直接向写入某些不带TargetFramework后缀的文件,包括:
AppendTargetFrameworkToOutputPath=trueIntermediateOutputPath- (NuGet还原输出)
project.assets.json - 其他NuGet相关文件
这会导致并行还原过程中出现这类错误。
Cannot create a file when that file already exists修复: 每个项目必须有独立的,不要跨项目共享中间输出目录:
BaseIntermediateOutputPathxml
<!-- 项目A -->
<BaseIntermediateOutputPath>..\obj\ProjectA\</BaseIntermediateOutputPath>
<!-- 项目B -->
<BaseIntermediateOutputPath>..\obj\ProjectB\</BaseIntermediateOutputPath>或者直接使用SDK默认配置,将目录放在每个项目的目录下。
objRuntimeIdentifier builds clashing
RuntimeIdentifier构建冲突
Problem: Building for multiple RIDs without RID in path.
Fix: Ensure RuntimeIdentifier is in the path:
xml
<AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>问题: 为多个RID构建但路径中未包含RID。
修复: 确保路径中包含RuntimeIdentifier:
xml
<AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>Multiple solutions building the same project
多个解决方案构建同一个项目
Problem: A single build invokes multiple solutions (e.g., via MSBuild task or command line) that include the same project. Each solution build evaluates and builds the project independently, with different global properties that don't affect the output path.
Solution*How to detect: Compare and across evaluations for the same project. Different values indicate multi-solution builds. For example:
SolutionFileNameCurrentSolutionConfigurationContents| Property | Eval from Solution A | Eval from Solution B |
|---|---|---|
| | |
| 1 project entry | ~49 project entries |
| | |
Example: A repo build script builds then , and both solutions include . Both builds write to . The first build compiles; the second skips compilation but still runs .
BuildAnalyzers.slnMain.slnxSharedAnalyzers.csprojbin\Release\netstandard2.0\CopyFilesToOutputDirectoryFix: Options include:
- Consolidate solutions - Ensure each project is only built from one solution in a single build
- Use different configurations - Build solutions with different values that result in different output paths
Configuration - Exclude duplicate projects - Use solution filters or conditional project inclusion to avoid building the same project twice
问题: 单次构建流程调用了多个解决方案(例如通过MSBuild任务或命令行),这些解决方案包含同一个项目。每个解决方案构建会独立评估和构建该项目,使用不同的全局属性,而这些属性不会影响输出路径。
Solution*检测方式: 对比同一个项目不同评估的和,值不同说明存在多解决方案构建。例如:
SolutionFileNameCurrentSolutionConfigurationContents| 属性 | 从解决方案A评估 | 从解决方案B评估 |
|---|---|---|
| | |
| 1个项目条目 | 约49个项目条目 |
| | |
示例: 代码库构建脚本先构建再构建,两个解决方案都包含,两次构建都写入。第一次构建完成编译,第二次构建跳过编译但仍会执行。
BuildAnalyzers.slnMain.slnxSharedAnalyzers.csprojbin\Release\netstandard2.0\CopyFilesToOutputDirectory修复: 可选方案包括:
- 合并解决方案——确保单次构建流程中每个项目仅被一个解决方案构建
- 使用不同配置——为不同解决方案构建使用不同的值,生成不同的输出路径
Configuration - 排除重复项目——使用解决方案过滤器或条件项目引入逻辑,避免重复构建同一个项目
Extra global properties creating redundant project instances
额外全局属性生成冗余项目实例
Problem: A project is built multiple times within the same solution due to extra global properties (e.g., ) that create distinct MSBuild project instances. These properties don't affect output paths but prevent MSBuild from caching results across instances, causing redundant target execution.
PublishReadyToRun=falseHow to detect: Compare global properties across evaluations for the same project within the same solution (same ). Look for properties that differ but don't contribute to path differentiation:
SolutionFileName| Property | Eval A (from Razor.slnx) | Eval B (from Razor.slnx) |
|---|---|---|
| (not set) | |
| | |
This is particularly wasteful for projects where the extra property has no effect (e.g., on a class library that doesn't use ReadyToRun compilation).
PublishReadyToRunnetstandard2.0Fix: Options include:
- Remove the extra global property - Investigate which parent target/task is injecting the property and prevent it from being passed to projects that don't need it
- Use metadata - On
RemoveGlobalPropertiesitems, useProjectReferenceto strip the property before building the referenced projectRemoveGlobalProperties="PublishReadyToRun" - Condition the property - Only set the property on projects that actually use it (e.g., only for executable projects, not class libraries)
问题: 同一个解决方案内的项目被多次构建,原因是额外的全局属性(例如)生成了独立的MSBuild项目实例。这些属性不会影响输出路径,但会阻止MSBuild跨实例缓存结果,导致目标重复执行。
PublishReadyToRun=false检测方式: 对比同一个解决方案内(相同)同一个项目的不同评估的全局属性,查找存在差异但不会影响路径区分的属性:
SolutionFileName| 属性 | 评估A(来自Razor.slnx) | 评估B(来自Razor.slnx) |
|---|---|---|
| (未设置) | |
| | |
对于额外属性没有实际作用的项目,这种问题尤其浪费资源(例如类库不需要ReadyToRun编译,设置没有作用)。
netstandard2.0PublishReadyToRun修复: 可选方案包括:
- 移除额外全局属性——排查是哪个父目标/任务注入了该属性,避免将其传递给不需要的项目
- 使用元数据——在
RemoveGlobalProperties项上配置ProjectReference,在构建引用项目前剥离该属性RemoveGlobalProperties="PublishReadyToRun" - 为属性添加条件——仅在实际需要的项目上设置该属性(例如仅对可执行项目设置,不对类库设置)
Example Workflow
示例工作流
bash
undefinedbash
undefined1. Replay the binlog
1. 重放binlog
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log
2. List projects
2. 列出项目
grep 'done building project' full.log | grep -oP '"[^"]+.csproj"' | sort -u
grep 'done building project' full.log | grep -oP '"[^"]+.csproj"' | sort -u
3. Check OutputPath for each evaluation
3. 检查每次评估的OutputPath
grep -i 'OutputPath\s*=' full.log | sort -u
grep -i 'OutputPath\s*=' full.log | sort -u
e.g. OutputPath = bin\Debug\net8.0\
示例输出: OutputPath = bin\Debug\net8.0\
OutputPath = bin\Debug\net9.0\
OutputPath = bin\Debug\net9.0\
4. Check IntermediateOutputPath
4. 检查IntermediateOutputPath
grep -i 'IntermediateOutputPath\s*=' full.log | sort -u
grep -i 'IntermediateOutputPath\s*=' full.log | sort -u
e.g. IntermediateOutputPath = obj\Debug\net8.0\
示例输出: IntermediateOutputPath = obj\Debug\net8.0\
IntermediateOutputPath = obj\Debug\net9.0\
IntermediateOutputPath = obj\Debug\net9.0\
5. Compare paths → No clash (paths differ by TargetFramework)
5. 对比路径 → 无冲突(路径按TargetFramework区分)
undefinedundefinedTips
提示
- Use to quickly find all OutputPath property assignments
grep -i 'OutputPath\s*=' full.log | sort -u - Check and
BaseOutputPathas they form the root of output pathsBaseIntermediateOutputPath - The SDK default paths include - clashes often occur when projects override these defaults
$(TargetFramework) - Remember that paths may be relative - normalize to absolute paths before comparing
- Cross-project IntermediateOutputPath clashes cannot be fixed with - files like
AppendTargetFrameworkToOutputPathare written directly to the intermediate pathproject.assets.json - For multi-targeting clashes within the same project, is the correct fix
AppendTargetFrameworkToOutputPath=true - Common error messages indicating path clashes:
- (NuGet restore)
Cannot create a file when that file already exists The process cannot access the file because it is being used by another process- Intermittent build failures that succeed on retry
- 使用可快速查找所有OutputPath属性配置
grep -i 'OutputPath\s*=' full.log | sort -u - 检查和
BaseOutputPath,因为它们是输出路径的根路径BaseIntermediateOutputPath - SDK默认路径包含——项目覆盖这些默认配置时通常会出现冲突
$(TargetFramework) - 注意路径可能是相对路径——对比前请先标准化为绝对路径
- 跨项目的IntermediateOutputPath冲突无法通过修复——
AppendTargetFrameworkToOutputPath这类文件会直接写入中间路径project.assets.json - 同一个项目内的多目标冲突,正确修复方案是设置
AppendTargetFrameworkToOutputPath=true - 提示路径冲突的常见错误信息:
- (NuGet还原阶段)
Cannot create a file when that file already exists The process cannot access the file because it is being used by another process- 重试后可成功的偶现构建失败
Global Properties to Check When Comparing Evaluations
对比评估时需要检查的全局属性
When multiple evaluations share an output path, compare these global properties to understand why:
| Property | Affects OutputPath? | Notes |
|---|---|---|
| Yes | Different TFMs should have different paths |
| Yes | Different RIDs should have different paths |
| Yes | Debug vs Release |
| Yes | AnyCPU vs x64 etc. |
| No | Identifies which solution built the project — different values indicate multi-solution clash |
| No | Solution name without extension |
| No | Full path to the solution file |
| No | Directory containing the solution file |
| No | XML with project entries — count of entries reveals which solution |
| No | |
| No | Present = restore phase evaluation |
| No | Publish setting, doesn't change build output path but creates distinct project instances |
当多个评估共享同一个输出路径时,对比以下全局属性可定位原因:
| 属性 | 是否影响OutputPath? | 说明 |
|---|---|---|
| 是 | 不同TFM应该有不同路径 |
| 是 | 不同RID应该有不同路径 |
| 是 | Debug与Release的区别 |
| 是 | AnyCPU与x64等的区别 |
| 否 | 标识构建项目的解决方案——值不同说明是多解决方案冲突 |
| 否 | 不带后缀的解决方案名称 |
| 否 | 解决方案文件的完整路径 |
| 否 | 解决方案文件所在目录 |
| 否 | 包含项目条目的XML——条目数量可识别对应的解决方案 |
| 否 | |
| 否 | 存在该属性说明是还原阶段评估 |
| 否 | 发布设置,不会修改构建输出路径但会生成独立的项目实例 |
Testing Fixes
测试修复效果
After making changes to fix path clashes, clean and rebuild to verify. See the skill's "Cleaning the Repository" section on how to clean the repository while preserving binlog files.
binlog-generation修改配置修复路径冲突后,请清理并重新构建验证效果。清理代码库同时保留binlog文件的方法可参考技能的「清理代码库」章节。
binlog-generation