Windows下动态加载含System.IO.Ports的程序集时抛出平台异常
动态加载引用System.IO.Ports的类库时抛出"仅支持Windows"异常的原因及解决方法
问题根源
直接引用类库时,MSBuild会根据主项目的net8.0-windows目标框架,自动处理System.IO.Ports的平台特定依赖:它会把Windows专属的实现DLL复制到输出目录,编译阶段就绑定了正确的平台上下文,运行时自然能找到对应实现。
但用Assembly.LoadFrom动态加载时,默认加载上下文不会继承主应用的目标平台绑定信息。System.IO.Ports的NuGet包包含多平台实现,加载器如果没有明确的平台上下文提示,会尝试加载通用版本——这个版本在运行时会检查应用的目标平台标识(而非当前系统),发现标识不匹配就抛出异常,哪怕OperatingSystem.IsWindows()返回true也没用。
解决方案
1. 用自定义AssemblyLoadContext指定依赖加载顺序
创建自定义加载上下文,先加载Windows版本的System.IO.Ports.dll,再加载目标类库,确保依赖解析走正确的平台实现:
using System.Reflection; using System.Runtime.Loader; using System.IO; try { var serialPortPath = "..\\..\\..\\..\\SerialPort\\bin\\Debug\\net8.0-windows\\SerialPort.dll"; var libDir = Path.GetDirectoryName(serialPortPath); var loadContext = new AssemblyLoadContext(null, isCollectible: false); // 先加载Windows版的System.IO.Ports loadContext.LoadFromAssemblyPath(Path.Combine(libDir, "System.IO.Ports.dll")); // 再加载目标类库 var serialAssembly = loadContext.LoadFromAssemblyPath(serialPortPath); var serialPort = Activator.CreateInstance(serialAssembly.GetType("SerialPort.SerialPort")); } catch (Exception ex) { // 可添加异常日志逻辑 Console.WriteLine(ex.Message); }
2. 给主项目明确指定RuntimeIdentifier
修改控制台应用的项目文件,添加RuntimeIdentifier配置,强制运行时绑定Windows平台:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0-windows</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <!-- 新增配置 --> <RuntimeIdentifier>win-x64</RuntimeIdentifier> </PropertyGroup> </Project>
重新生成后,主应用的输出目录会包含Windows专属的依赖组件,动态加载时就能正确解析。
3. 手动复制平台依赖文件
把类库输出目录中的System.IO.Ports.dll和相关Windows平台文件,复制到控制台应用的输出目录,让动态加载器能直接找到正确的实现。
内容的提问来源于stack exchange,提问作者grandangelo
相关产品推荐
相关产品推荐

