PowerShell Core 7.4.2加载.NET 8.0自定义DLL失败求助
问题根源与解决方法
核心问题
你遇到的加载失败,本质是PowerShell Core 7.4.2的运行时依赖与编译的程序集版本不匹配:
- PowerShell 7.4.x基于.NET 7 runtime运行,直接用
[Reflection.Assembly]::LoadFile加载.NET 8编译的程序集,会触发跨大版本的.NET程序集加载冲突。 .NET Core/.NET 5+的程序集加载模型和.NET Framework完全不同,LoadFile这种底层反射加载方式无法处理.NET 5+的依赖解析逻辑,导致基础程序集(如System.Runtime)绑定失败,甚至出现System.Object找不到的极端情况——这是因为加载上下文混乱,.NET 8的基础类型无法和PowerShell当前的.NET 7 runtime兼容。
错误操作点
- 用
[Reflection.Assembly]::LoadFile加载.NET 5+程序集:该方法仅适合.NET Framework场景,不支持.NET Core/.NET的模块化依赖解析。 - 手动添加System.Runtime等基础程序集:这会导致版本冲突,PowerShell已经自带对应.NET 7版本的基础程序集,强行引入.NET 8版本会破坏类型系统一致性。
正确解决方式
方式1:匹配目标框架版本(推荐)
将test.dll的编译目标框架改为**.NET 7**(和PowerShell 7.4的依赖版本一致),编译完成后直接用以下命令加载:
Add-Type -Path "C:\test\test.dll"
之后即可正常调用[Some.NameSpace.ClassName]::DoSth("your-file-path")。
方式2:适配.NET 8程序集的加载(仅当必须用.NET 8编译时)
如果必须保留.NET 8编译的程序集,需要借助.NET的AssemblyLoadContext来隔离加载上下文:
- 编写一个简单的.NET类库(用.NET 8编译),实现自定义加载上下文:
using System.Runtime.Loader; using System.IO; namespace AssemblyLoader { public class CustomLoadContext : AssemblyLoadContext { private string _assemblyPath; public CustomLoadContext(string assemblyPath) : base(isCollectible: true) { _assemblyPath = Path.GetDirectoryName(assemblyPath); } protected override System.Reflection.Assembly Load(System.Reflection.AssemblyName assemblyName) { // 优先从程序集所在目录加载依赖 string assemblyFilePath = Path.Combine(_assemblyPath, $"{assemblyName.Name}.dll"); if (File.Exists(assemblyFilePath)) { return LoadFromAssemblyPath(assemblyFilePath); } // 找不到则回退到默认加载上下文 return Default.LoadFromAssemblyName(assemblyName); } } }
- 将这个类库编译后,在PowerShell中先加载这个加载器,再加载你的
test.dll:
# 加载自定义加载器 Add-Type -Path "C:\test\AssemblyLoader.dll" # 创建加载上下文,指定test.dll的目录 $loadContext = [AssemblyLoader.CustomLoadContext]::new("C:\test\test.dll") # 加载目标程序集 $assembly = $loadContext.LoadFromAssemblyPath("C:\test\test.dll") # 获取类型并调用方法 $type = $assembly.GetType("Some.NameSpace.ClassName") $type.GetMethod("DoSth").Invoke($null, @("your-file-path"))
额外注意
你的test.dll引用了Microsoft.Win32相关API,在.NET 5+中需要安装Microsoft.Win32.Registry NuGet包才能编译通过,否则会出现依赖缺失错误。
内容的提问来源于stack exchange,提问作者TomB
相关产品推荐
相关产品推荐

