dotnet run与dotnet build执行行为差异问题排查
问题描述
我有一个C#项目,配置了预构建(PreBuild)和后构建(PostBuild)目标:预构建通过Exec标签将项目外目录的文件复制到目标目录;后构建先运行项目(依赖复制的文件)生成新文件,再将生成文件复制到目标文件夹内的另一个目录。相关MSBuild配置如下:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net6.0</TargetFramework> <RestoreEnablePackagesConfig>false</RestoreEnablePackagesConfig> </PropertyGroup> <Target Name="PreBuild" BeforeTargets="BeforeBuild"> <Exec WorkingDirectory="$(MSBuildProjectDirectory)" Command="xcopy ..\SomeInputFiles\ $(TargetDir)\InputFiles\ /s /e /y" /> </Target> <Target Name="PostBuild" AfterTargets="PostBuildEvent"> <Exec Command="dotnet $(TargetDir)\My.Project.dll" /> <Exec Command="xcopy $(TargetDir)\OutputFiles\ $(TargetDir)..\..\..\Output\OutputFiles\ /s /e /y" /> </Target> </Project>
执行dotnet build时,文件夹结构正常,Project/target/Output/OutputFiles可成功获取生成的文件;但执行dotnet run时,Project/target/distrib/My.Project/net6.0/OutputFiles有生成文件,Project/target/Output/OutputFiles却为空,似乎后构建的xcopy步骤未执行,请问该行为差异的原因是什么?
原因分析
- 输出目录差异:
dotnet run默认将编译输出放到临时发布目录(如Project/target/distrib/My.Project/net6.0/),而dotnet build使用常规框架输出目录。你的PostBuild目标中$(TargetDir)在dotnet run场景下指向临时目录,导致xcopy的源路径是临时目录的OutputFiles,但目标路径$(TargetDir)..\..\..\Output\OutputFiles基于临时目录回溯后,并非你预期的Project/target/Output/OutputFiles,最终没有文件复制到目标位置。 - 构建目标执行逻辑不同:
dotnet run的构建流程触发的MSBuild目标链与dotnet build有差异。你的自定义PostBuild目标绑定了PostBuildEvent,在dotnet run场景下,该目标可能因构建流程优化(比如检测到项目已构建完成)被跳过,导致xcopy步骤未执行。 - 相对路径依赖问题:你使用的多层向上回溯相对路径
..\..\..\完全依赖$(TargetDir)的目录结构。当dotnet run和dotnet build的$(TargetDir)结构不同时,回溯后的目标路径会偏离预期,直接导致复制失败。
内容的提问来源于stack exchange,提问作者ROODAY
相关产品推荐
相关产品推荐

