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

net48 SolidWorks插件加载System.Text.Json报程序集加载异常求解

.NET Framework 4.8环境下SolidWorks插件加载System.Text.Json程序集异常问题根因分析

问题背景

  • 开发场景:面向.NET Framework 4.8(net48)的SolidWorks C#类库插件,通过RegAsm.exe /codebase注册为COM组件供SolidWorks加载
  • 项目依赖:com.solidworks.core 29.5.1、com.solidworks.tools 21.5.0、System.Text.Json 6.0.2
  • 触发场景:执行System.Text.Json.JsonDocument.Parse(jsonText)时抛出文件找不到异常
  • 异常信息:

Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

已尝试操作与待确认疑问

  • 已在csproj中开启自动生成绑定重定向配置:
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>

生成的dll.config中已配置System.Runtime.CompilerServices.Unsafe 0.0.0.0-6.0.0.0版本统一重定向到6.0.0.0,但异常仍然存在。

  • 项目输出目录bin\Debug\net48下已存在版本匹配的文件:System.Text.Json.dll(6.0.0.2,清单中引用Unsafe 6.0.0.0)、System.Runtime.CompilerServices.Unsafe.dll(6.0.0.0),需要确认:
    • CLR加载System.Text.Json.dll的搜索路径、加载System.Runtime.CompilerServices.Unsafe.dll的搜索路径具体包含哪些位置,是否包含GAC
  • 相同逻辑的独立net48控制台程序运行无异常,确认问题和SolidWorks宿主环境相关
  • VS调试模块窗口显示:异常触发前System.Text.Json 6.0.0.0已经从项目输出目录加载,Unsafe程序集尚未加载,需要确认:
    • 为什么CLR会尝试加载4.0.4.1版本的Unsafe,而非System.Text.Json清单中引用的6.0.0.0版本
    • 4.0.4.1这个版本号的具体来源

根因解析

1. 绑定重定向失效的核心原因

COM加载场景下,CLR默认读取的是宿主进程(也就是SolidWorks.exe)同目录下的SolidWorks.exe.config作为程序集绑定配置文件,不会自动读取插件dll同目录下的插件名.dll.config,这就是配置了绑定重定向却完全不生效的直接原因。
控制台程序能正常运行,是因为控制台程序是进程主入口,CLR会自动读取exe同目录下的xxx.exe.config配置,绑定重定向可以正常生效。

2. 4.0.4.1版本号的来源

这个版本号是SolidWorks进程已经加载的其他依赖项携带的引用:SolidWorks本身以及其预装的大量官方/第三方插件、扩展模块,很多会依赖旧版本的System.Runtime.CompilerServices.Unsafe(4.0.4.1是该库的经典旧版本号,对应4.x系列的正式发行版)。
CLR在net48环境下处理程序集加载请求时,会优先检查当前进程内已经存在的程序集引用版本记录:当加载的System.Text.Json触发Unsafe加载需求时,CLR发现进程内已经有对Unsafe 4.0.4.1版本的引用记录,又因为绑定重定向配置根本没被CLR读取,所以CLR不会做版本重定向,直接尝试加载4.0.4.1版本的Unsafe。

3. CLR程序集搜索路径规则

CLR的程序集加载搜索优先级如下,GAC优先级远高于本地目录:

  • 第一步:检查全局程序集缓存(GAC),如果找到匹配版本的程序集直接加载,不会继续搜索本地路径
  • 第二步:通过触发加载的程序集的CodeBase属性确定基础搜索路径:System.Text.Json是从插件输出目录加载的,所以它触发的依赖搜索基础路径是插件输出目录,但注意如果没有对应的绑定配置,CLR只会搜索完全匹配请求版本号的dll,不会自动加载高版本dll
  • 第三步:依次检查宿主进程目录、系统目录、PATH环境变量包含的目录
    本地输出目录里的Unsafe是6.0.0.0版本,和CLR当前请求的4.0.4.1版本号不匹配,所以即使文件存在也不会被识别加载。

可行解决方案

  • 方案1(侵入性最低,推荐):在插件代码中订阅AppDomain.CurrentDomain.AssemblyResolve事件,在事件中手动加载输出目录下的对应版本Unsafe、System.Text.Json等依赖dll,完全绕开默认的绑定逻辑:
// 在插件入口点(比如COM注册的Connect方法最开始位置)注册事件
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var assemblyName = new AssemblyName(args.Name);
    var dllPath = Path.Combine(Path.GetDirectoryName(typeof(插件入口类).Assembly.Location), 
        $"{assemblyName.Name}.dll");
    return File.Exists(dllPath) ? Assembly.LoadFrom(dllPath) : null;
};
  • 方案2:手动把插件dll.config里的绑定重定向配置,合并到SolidWorks安装目录下的SolidWorks.exe.config文件中,注意修改前备份原配置,避免影响SolidWorks本身运行。
  • 方案3:构建插件时把System.Text.Json相关的所有依赖dll都设置为ILMerge合并到插件单dll中,避免外部依赖搜索。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:24:34