如何将项目文件复制到输出目录并导入同解决方案项目代码?
解决方案
问题根源
添加ProjectReference后,MSBuild会自动处理AppProject的依赖输出(包括编译产物、必要的项目文件),而你之前配置的<None>节点会将AppProject的源码文件完整复制到TestProject的输出目录。在Linux环境下,MSBuild对文件路径的冲突检测更严格,两者复制的文件出现路径重叠(比如部分配置文件、源码文件),导致"文件已存在"的错误。
修正现有配置的方法
你可以调整原有的<None>配置,排除ProjectReference已经自动处理的文件,同时修改复制路径避免重叠:
<ItemGroup> <!-- 排除ProjectReference会输出的编译产物及已处理文件,同时将源码复制到独立子目录 --> <None Include="..\AppProject\**" Exclude="..\AppProject\bin\**;..\AppProject\obj\**;..\AppProject\**\*.dll;..\AppProject\**\*.pdb;..\AppProject\**\*.deps.json;..\AppProject\**\*.runtimeconfig.json"> <Link>AppProjectSources\%(RecursiveDir)%(Filename)%(Extension)</Link> <PackageCopyToOutput>true</PackageCopyToOutput> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> <ItemGroup> <ProjectReference Include="..\AppProject\AppProject.csproj" /> </ItemGroup>
关键调整点:
- 将复制的源码放到
AppProjectSources子目录,和ProjectReference输出的文件路径彻底分离 - 改用
PreserveNewest替代Always,减少不必要的复制操作 - 排除ProjectReference已输出的编译产物文件(dll、pdb、依赖配置文件等)
更优方案:使用自定义MSBuild目标替代复制
放弃原有的<None>配置,改用自定义MSBuild目标在构建完成后同步AppProject源码,避免和ProjectReference的内置逻辑冲突:
<ItemGroup> <ProjectReference Include="..\AppProject\AppProject.csproj" /> <!-- 定义需要复制的AppProject源文件集合 --> <AppProjectSourceFiles Include="..\AppProject\**" Exclude="..\AppProject\bin\**;..\AppProject\obj\**;..\AppProject\**\*.dll;..\AppProject\**\*.pdb" /> </ItemGroup> <!-- 在TestProject构建完成后执行源码复制 --> <Target Name="SyncAppProjectSources" AfterTargets="Build"> <Copy SourceFiles="@(AppProjectSourceFiles)" DestinationFiles="@(AppProjectSourceFiles->'$(OutputPath)AppProject\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" /> </Target>
这种方式的优势:
- 复制逻辑独立于项目文件的内置处理流程,不会和ProjectReference的文件输出产生冲突
SkipUnchangedFiles可以提升构建效率,只复制更新过的文件
额外优化思路
如果你的核心需求是在TestProject输出目录执行dotnet publish AppProject,其实不需要复制AppProject源码到TestProject输出目录。可以直接通过相对路径指向解决方案中的AppProject:
比如在TestProject的代码中,执行命令时使用:
dotnet publish "../../AppProject/AppProject.csproj" -o "./published-app"
(路径根据你的解决方案目录结构调整)
这种方式完全避免了文件复制的问题,同时更符合.NET项目的依赖管理逻辑。
内容的提问来源于stack exchange,提问作者Trevor Thoele
相关产品推荐
相关产品推荐

