.NET 6运行时加载.NET Standard 2.1程序集至AppDomain报错求助
问题分析与解决方案
问题背景
将.NET 4.6 FullFramework类库迁移至.NET Standard 2.1后,.NET 6应用通过遍历目录抓取*.dll并调用AppDomain.CurrentDomain.Load(AssemblyName)加载时,抛出错误:
"Could not load file or assembly 'Framework.Tests.NetCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, processorArchitecture=MSIL'. 系统无法找到指定文件。"
核心原因
.NET 6(及其他.NET Core系列框架)中,AppDomain的加载逻辑与.NET Framework存在本质差异:
AppDomain.Load(AssemblyName)依赖程序集名称在默认探测路径(如应用执行目录、配置的私有路径)中查找匹配文件,若待加载DLL不在这些路径内,仅通过AssemblyName无法定位到文件。- .NET Standard是抽象契约,虽.NET 6兼容.NET Standard 2.1,但加载时仍需确保程序体文件及依赖处于可被探测到的位置。
解决方案
方案1:直接从文件路径加载(推荐,适配.NET 6机制)
将原代码中通过AssemblyName加载的逻辑替换为直接从文件路径加载,绕过名称查找的限制:
private void LoadMatchingAssemblies(string directoryPath) { foreach (var dllPath in Directory.GetFiles(directoryPath, "*.dll")) { try { var an = AssemblyName.GetAssemblyName(dllPath); if (this.Matches(an.FullName) && !loadedAssemblyNames.Contains(an.FullName)) { // 替换AppDomain.Load(an)为Assembly.LoadFrom Assembly.LoadFrom(dllPath); loadedAssemblyNames.Add(an.FullName); } } catch (BadImageFormatException) { } catch(Exception e) { string es = e.Message; } } }
该方式直接指定文件路径加载,无需依赖程序集探测路径,同时加载后的程序集会被当前AppDomain识别。
方案2:将待加载DLL纳入应用探测路径
- 方式A:复制DLL到执行目录
把目标.NET Standard 2.1 DLL及其依赖复制到.NET 6应用的输出目录(如bin/Debug/net6.0),确保AppDomain能通过AssemblyName找到文件。 - 方式B:配置私有探测路径
在.NET 6应用的Program.cs中,添加以下代码(注意AppendPrivatePath已过时,但仍可在.NET 6中使用):
此操作会将目标目录添加到AppDomain.CurrentDomain.AppendPrivatePath(directoryPath);AppDomain的私有探测路径,让AppDomain.Load(AssemblyName)能在该目录下查找程序集。
方案3:验证AssemblyName正确性
部分场景下,AssemblyName.GetAssemblyName(dllPath)获取的名称可能存在偏差(如版本号、公钥令牌不匹配),可直接输出an.FullName与错误信息中的程序集名称对比,确认是否一致。若存在差异,需修正匹配逻辑或确保DLL的AssemblyName与预期一致。
内容的提问来源于stack exchange,提问作者KnApP993
相关产品推荐
相关产品推荐

