MSBuild命令执行时非必要文件夹被复制至.NET Core输出路径问题咨询
问题
我有一个单体解决方案,包含两类项目:
- 基于.NET Framework 4.8运行的项目
- 基于.NET Core 3.1运行的项目
其中:
- .NET Framework 4.8项目的输出路径为
c:\product - .NET Core 3.1项目(RemotePatching)的输出路径为
c:\product\Remotepatching,且该项目依赖一个.NET Framework 4.8项目(PlatformServices)
执行的MSBuild命令:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\msbuild.exe" "C:\Sources\APM.sln" /p:platform="x64" /p:configuration="release"
运行上述命令构建解决方案时,c:\product下的所有文件夹都会被复制到c:\product\Remotepatching中;但如果移除.NET Core 3.1项目的依赖关系,则不会出现该复制行为。
请问我的MSBuild命令是否存在遗漏配置?
RemotePatching项目的项目文件:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <ProductSubdirectory>RemotePatching</ProductSubdirectory> </PropertyGroup> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AssemblyOriginatorKeyFile>Properties\StrongNameKey.snk</AssemblyOriginatorKeyFile> <ApplicationIcon /> <OutputType>WinExe</OutputType> <StartupObject /> <SignAssembly>true</SignAssembly> <DelaySign>false</DelaySign> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <OutputPath>..\..\Product\RemotePatching\</OutputPath> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> <DefineConstants>DEBUG;TRACE;$(BuildServerConstants)</DefineConstants> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <DebugSymbols>true</DebugSymbols> <Optimize>false</Optimize> <WarningsAsErrors /> <WarningLevel>4</WarningLevel> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"> <OutputPath>..\..\Product\RemotePatching\</OutputPath> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> <DefineConstants>TRACE;$(BuildServerConstants)</DefineConstants> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <DebugSymbols>true</DebugSymbols> <Optimize>true</Optimize> <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" /> </ItemGroup> <ItemGroup> <Reference Include="PlatformServices"> <HintPath>..\..\Product\PlatformServices.dll</HintPath> </Reference> </ItemGroup> </Project>
解决方案分析
这不是MSBuild命令的问题,而是项目依赖配置导致的默认行为:
核心原因:RemotePatching项目通过
<Reference>直接引用了c:\product目录下的PlatformServices.dll,MSBuild在处理这种文件级引用时,会默认将该DLL所在目录下的所有关联文件、子文件夹都复制到项目输出目录,以保证依赖项能被正确加载运行。可行解决办法:
- 改用项目引用替代文件引用:如果PlatformServices是解决方案内的项目,将现有文件引用替换为项目引用,MSBuild只会复制该项目的输出文件,不会复制整个目录:
<ItemGroup> <ProjectReference Include="..\Relative\Path\To\PlatformServices.csproj"> <Project>{对应项目的GUID}</Project> <Name>PlatformServices</Name> </ProjectReference> </ItemGroup> - 限制文件复制范围:如果必须保留文件引用,可设置
Private属性为false,并手动指定需要复制的文件,避免整个目录被复制:
再单独添加需要复制到输出目录的文件:<Reference Include="PlatformServices"> <HintPath>..\..\Product\PlatformServices.dll</HintPath> <Private>false</Private> </Reference><ItemGroup> <None Include="..\..\Product\PlatformServices.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> - 调整输出路径实现隔离:将.NET Framework项目的输出路径改为
c:\product\Framework,RemotePatching的输出路径保持c:\product\Remotepatching,从目录结构上避免因层级关联导致的自动复制问题。
- 改用项目引用替代文件引用:如果PlatformServices是解决方案内的项目,将现有文件引用替换为项目引用,MSBuild只会复制该项目的输出文件,不会复制整个目录:
内容的提问来源于stack exchange,提问作者Sandhya Ratan
相关产品推荐
相关产品推荐

