Visual Studio 2017编译多目标框架项目遇MSB3644错误求助
在Visual Studio 2017中编译包含.NET 6.0及多个netstandard版本的多目标项目时,出现MSB3644错误。即使安装了包含.NET Runtime 6.x.x、ASP.NET Core Runtime 6.x.x、.NET Desktop Runtime 6.x.x的.NET 6.0环境,问题仍未解决。解决方案资源管理器中的依赖项也显示错误(截图显示依赖项带有红色错误标记)。
已安装的SDK与global.json配置兼容,文件内容如下:
{ "sdk": { "version": "6.0.401", "allowPrerelease": false, "rollForward": "feature" } }
完整错误信息:
错误代码MSB3644:未找到框架“.NETFramework,Version=v6.0”的引用程序集。要解决此问题,请安装该框架版本的SDK或目标包,或将应用重新定向到已安装SDK或目标包的框架版本。请注意,程序集将从全局程序集缓存(GAC)解析,并将替代引用程序集使用。因此,程序集可能无法正确定向到预期的框架。
该错误同样适用于所有缺失或无法识别的依赖项。
项目的.csproj目标框架配置如下(已修正原配置中的语法错误):
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>netstandard2.1;netstandard2.0;net45;net48;netstandard1.5;net40;net35;net20;net6.0</TargetFrameworks> </PropertyGroup> <PropertyGroup Condition="'$(TargetFramework)' == 'net20' "> <DefineConstants>$(DefineConstants);LEGACY</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(TargetFramework)' == 'net35' "> <DefineConstants>$(DefineConstants);LEGACY</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(TargetFramework)' == 'net40' "> <DefineConstants>$(DefineConstants);LEGACY</DefineConstants> </PropertyGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' "> <PackageReference Include="System.Collections.NonGeneric" Version="4.0.1" /> <PackageReference Include="System.Collections.Specialized" Version="4.0.1" /> <PackageReference Include="System.Reflection" Version="4.3.0" /> <PackageReference Include="System.Reflection.TypeExtensions" Version="4.1.0" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net20" Version="1.0.3" Condition="'$(TargetFramework)' == 'net20' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net35" Version="1.0.3" Condition="'$(TargetFramework)' == 'net35' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net40" Version="1.0.3" Condition="'$(TargetFramework)' == 'net40' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net45" Version="1.0.3" Condition="'$(TargetFramework)' == 'net45' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net48" Version="1.0.3" Condition="'$(TargetFramework)' == 'net48' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> </ItemGroup> </Project>
问题原因
Visual Studio 2017的原生工具集不支持.NET 6.0(.NET 6于2021年发布,VS2017官方仅支持到.NET Core 2.1)。即使安装了.NET 6 SDK,VS2017的MSBuild无法识别net6.0作为有效目标框架,导致引用程序集找不到。
解决方案
1. 升级Visual Studio版本(推荐)
将Visual Studio 2017升级到Visual Studio 2022或Visual Studio 2019,这两个版本原生支持.NET 6.0,无需额外配置即可编译多目标项目。
2. 使用dotnet CLI编译项目
如果必须保留VS2017,可在外部使用.NET 6 SDK的命令行工具编译:
- 打开命令行,导航到项目目录
- 执行命令:
dotnet build
该命令直接调用已安装的.NET 6 SDK,不受VS2017工具集限制。
3. 为VS2017添加.NET 6引用程序集支持(兼容性有限)
在项目文件中添加.NET 6引用程序集的包引用,让MSBuild能找到对应的框架文件:
<ItemGroup> <!-- 保留原有.NET Framework引用包 --> <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net20" Version="1.0.3" Condition="'$(TargetFramework)' == 'net20' "> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> <!-- 其他.NET Framework引用包... --> <!-- 添加.NET 6引用程序集 --> <PackageReference Include="Microsoft.NETCore.App.Ref" Version="6.0.9" Condition="'$(TargetFramework)' == 'net6.0'"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference> </ItemGroup>
添加后清理项目并重新生成,但此方法可能仍存在兼容性问题,建议优先使用前两种方案。
内容的提问来源于stack exchange,提问作者shdr

