You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

制作支持多框架多架构的LibB nupkg遇依赖加载错误求助

问题描述

我有一个依赖LibA的类库LibB,其中LibA是依赖静态库NativeLibA的C++/CLI类库。我希望发布同时支持.NET Framework 4.7.2、.NET 8.0以及x86、x64架构的LibB NuGet包。由于LibA作为C++/CLI类库无法编译为NetStandard2.0,因此NuGet包中需要包含四个不同版本的LibA。我已经编写了如下csproj文件用于生成NuGet包:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netstandard2.0</TargetFrameworks>
    <PackageId>LibB</PackageId>
    <Title>Library B</Title>
    <Version>1.2.3.4</Version>
    <Authors>ACME</Authors>
    <Company>ACME</Company>
    <Description>Library B.</Description>
    <Copyright>Copyright © ACME 2025</Copyright>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="LibA">
      <HintPath>..\LibA\install\$(TargetFramework)\$(Platform)\LibA.dll</HintPath>
    </Reference>
  </ItemGroup>

  <ItemGroup>
    <!-- .NET Framework 4.7.2 x86 -->
    <None Include="..\LibA\install\net472\x86\LibA.dll" Pack="true" PackagePath="runtimes\win-x86\net472"/>
    <!-- .NET Framework 4.7.2 x64 -->
    <None Include="..\LibA\install\net472\x64\LibA.dll" Pack="true" PackagePath="runtimes\win-x64\net472"/>
    <!-- .NET Core 8.0 x86 -->
    <None Include="..\LibA\install\net8.0\x86\LibA.dll" Pack="true" PackagePath="runtimes\win-x86\net8.0"/>
    <None Include="..\LibA\install\net8.0\x86\Ijwhost.dll" Pack="true" PackagePath="runtimes\win-x86\net8.0"/>
    <!-- .NET Core 8.0 x64 -->
    <None Include="..\LibA\install\net8.0\x64\LibA.dll" Pack="true" PackagePath="runtimes\win-x64\net8.0"/>
    <None Include="..\LibA\install\net8.0\x64\Ijwhost.dll" Pack="true" PackagePath="runtimes\win-x64\net8.0"/>
  </ItemGroup>

</Project>

使用该文件生成NuGet包后,无论搭配何种框架或架构使用,都会出现如下错误:

Could not load file or assembly 'LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
in Calculator.Calculator.Add(Int32 a, Int32 b)
in App.Program.Main(String[] args) in C:\Users\Marco\source\repos\multiarch-nuget\Test\App.cs:riga 13

解决方案

1. 修正NuGet包文件布局

当前的PackagePath不符合.NET运行时自动加载规则,需要调整路径结构,让.NET能根据运行环境自动匹配对应的LibA:

修改后的文件打包配置:

<ItemGroup>
  <!-- .NET Framework 4.7.2 x86 -->
  <None Include="..\LibA\install\net472\x86\LibA.dll" Pack="true" PackagePath="runtimes\win-x86\lib\net472"/>
  <!-- .NET Framework 4.7.2 x64 -->
  <None Include="..\LibA\install\net472\x64\LibA.dll" Pack="true" PackagePath="runtimes\win-x64\lib\net472"/>
  <!-- .NET 8.0 x86 -->
  <None Include="..\LibA\install\net8.0\x86\LibA.dll" Pack="true" PackagePath="runtimes\win-x86\lib\net8.0"/>
  <None Include="..\LibA\install\net8.0\x86\Ijwhost.dll" Pack="true" PackagePath="runtimes\win-x86\lib\net8.0"/>
  <!-- .NET 8.0 x64 -->
  <None Include="..\LibA\install\net8.0\x64\LibA.dll" Pack="true" PackagePath="runtimes\win-x64\lib\net8.0"/>
  <None Include="..\LibA\install\net8.0\x64\Ijwhost.dll" Pack="true" PackagePath="runtimes\win-x64\lib\net8.0"/>
</ItemGroup>

2. 为LibB添加程序集解析逻辑

由于LibB基于NetStandard2.0,无法直接绑定特定架构的LibA,需要手动注册程序集解析事件,根据当前运行环境加载对应版本:

在LibB中添加初始化类:

using System;
using System.IO;
using System.Reflection;

namespace LibB
{
    public static class LibInitializer
    {
        static LibInitializer()
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        }

        private static Assembly? CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (!args.Name.StartsWith("LibA,")) return null;

            // 获取当前运行架构
            string arch = Environment.Is64BitProcess ? "x64" : "x86";
            // 判断当前运行框架
            string frameworkDir = Type.GetType("System.Runtime.Loader.AssemblyLoadContext") != null ? "net8.0" : "net472";

            // 拼接LibA的路径
            string libPath = Path.Combine(AppContext.BaseDirectory, $"runtimes\\win-{arch}\\lib\\{frameworkDir}\\LibA.dll");
            return File.Exists(libPath) ? Assembly.LoadFrom(libPath) : null;
        }

        // 确保初始化逻辑被触发
        public static void Initialize() {}
    }
}

使用LibB的项目需要在启动时调用初始化:

// 应用入口处添加
LibB.LibInitializer.Initialize();

3. 调整LibB的编译目标(可选但推荐)

将LibB的编译目标从仅NetStandard2.0改为同时支持net472和net8.0,避免跨框架的兼容性问题:

修改csproj中的TargetFrameworks:

<PropertyGroup>
  <TargetFrameworks>net472;net8.0</TargetFrameworks>
  <!-- 其他属性保持不变 -->
</PropertyGroup>

同时调整LibA的引用路径,适配不同编译目标:

<ItemGroup>
  <Reference Include="LibA">
    <HintPath>..\LibA\install\$(TargetFramework)\$(PlatformTarget)\LibA.dll</HintPath>
    <Private>false</Private>
  </Reference>
</ItemGroup>

这样编译后会生成对应框架的LibB版本,NuGet包会自动为不同框架分发匹配的LibA引用。

内容的提问来源于stack exchange,提问作者Marco Giglio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:54:59