面向.NET Framework 4.6.1的.NET Core项目无法加载NuGet包中非托管程序集
解决.NET Framework 4.6.1下无法加载runtime.native NuGet包中非托管程序集的问题
我之前也碰到过一模一样的情况——runtime.native.*这类NuGet包是专门为.NET Core/.NET 5+生态设计的,它们依赖.NET Core的运行时包存储机制自动处理原生库的分发和加载,但.NET Framework并不识别这种包结构,默认不会把非托管程序集复制到输出目录,自然就会出现加载失败的问题。
下面是具体的解决步骤:
1. 确认NuGet包的原生文件位置
先打开你的NuGet包缓存目录(通常是%userprofile%\.nuget\packages\runtime.native.company.project\1.0.0),找到runtimes文件夹,里面会按平台(比如win-x64、linux-x64)分类存放对应的非托管DLL。记好这些路径,后面要用到。
2. 修改项目文件,添加MSBuild目标自动复制原生库
在你的.csproj文件里,添加一个针对net461目标的MSBuild任务,让它在构建完成后把对应的原生库复制到输出目录。
示例1:固定复制Windows x64的原生库
如果你的应用只在Windows x64环境运行,直接用这个简单的配置:
<Target Name="CopyNativeLibsForNet461" AfterTargets="Build" Condition="'$(TargetFramework)' == 'net461'"> <ItemGroup> <NativeAssets Include="$(NuGetPackageRoot)runtime.native.company.project\1.0.0\runtimes\win-x64\native\*.dll" /> </ItemGroup> <Copy SourceFiles="@(NativeAssets)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> </Target>
示例2:根据当前构建平台自动匹配
如果需要跨平台支持,可以让MSBuild根据当前操作系统和架构自动选择对应的原生库:
<Target Name="CopyNativeLibsForNet461" AfterTargets="Build" Condition="'$(TargetFramework)' == 'net461'"> <PropertyGroup> <!-- 自动识别当前运行时平台 --> <RuntimePlatform Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-$(PlatformTarget.ToLower())</RuntimePlatform> <RuntimePlatform Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-$(PlatformTarget.ToLower())</RuntimePlatform> <RuntimePlatform Condition="$([MSBuild]::IsOSPlatform('OSX'))">osx-$(PlatformTarget.ToLower())</RuntimePlatform> </PropertyGroup> <ItemGroup> <NativeAssets Include="$(NuGetPackageRoot)runtime.native.company.project\1.0.0\runtimes\$(RuntimePlatform)\native\*.dll" /> </ItemGroup> <Copy SourceFiles="@(NativeAssets)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="true" /> </Target>
3. 验证解决方案
重新构建net461目标,然后检查输出目录(比如bin\Debug\net461),你应该能看到复制过来的非托管DLL。运行程序后,加载问题应该就解决了。
额外说明
.NET Framework加载非托管库时,会优先从可执行文件所在目录查找,所以把库复制到输出目录是最可靠的方式。如果你的应用需要部署到其他环境,记得把这些原生库一起打包分发。
内容的提问来源于stack exchange,提问作者Mackiovello
相关产品推荐
相关产品推荐

