.NET 6 Ubuntu构建时标准DLL被复制的控制方法咨询
解决.NET 6指定RuntimeIdentifier后构建输出大量标准DLL的问题
我完全理解你的困扰:把.NET Framework项目迁移到.NET 6后,为了统一Ubuntu部署的输出目录设置了ubuntu.22.04-x64作为RuntimeIdentifier,但执行dotnet build时,上百个System.*这类标准框架DLL都被复制到了输出文件夹——而目标机器明明已经装了dotnet runtime,根本不需要这些文件。
问题根源
当你在项目中指定RuntimeIdentifier时,即使没有开启自包含发布(默认SelfContained就是false),MSBuild会自动切换到RID专属的框架依赖构建模式。这种模式下,工具链会把适配该RID的框架组件也复制到输出,目的是兼容特定系统的本地特性,但对于已经预装runtime的机器来说,这完全是冗余的。
快速解决办法
你只需要在项目的主<PropertyGroup>里添加两个属性,就能精准控制这个行为:
<!-- 明确指定非自包含模式,避免RID触发默认行为变更 --> <SelfContained>false</SelfContained> <!-- 禁止复制框架依赖的标准DLL,只保留项目自身和第三方依赖 --> <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
把这两行加入到你的项目文件后,完整的PropertyGroup会变成这样:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <OutputType>Exe</OutputType> <RuntimeIdentifier>ubuntu.22.04-x64</RuntimeIdentifier> <TargetZone>LocalIntranet</TargetZone> <GenerateManifests>false</GenerateManifests> <SignManifests>false</SignManifests> <ReleaseVersion>4.4.0</ReleaseVersion> <UseMSBuildEngine>False</UseMSBuildEngine> <NoWin32Manifest>False</NoWin32Manifest> <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> <NoStdLib>False</NoStdLib> <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <ImportWindowsDesktopTargets>false</ImportWindowsDesktopTargets> <OutputPath>..\..\build\solutionname</OutputPath> <Deterministic>false</Deterministic> <!-- 新增的控制属性 --> <SelfContained>false</SelfContained> <CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies> </PropertyGroup> <!-- 其余项目内容不变 --> </Project>
补充说明
<CopyLocalLockFileAssemblies>这个属性是核心:它决定是否把NuGet锁定文件里的所有依赖都复制到输出。设为false后,只会复制你的项目编译产物、以及像Mono.Posix.NETStandard.dll这类必要的第三方依赖,.NET框架本身的标准DLL会被跳过。- 如果之后你需要针对某个特定第三方包调整复制行为,可以单独给该PackageReference设置
<PrivateAssets>或<CopyLocal>属性,但对于框架级的标准DLL,这个全局设置就足够解决问题了。
内容的提问来源于stack exchange,提问作者abulhol
相关产品推荐
相关产品推荐

