MEF CompositionException异常:MSIX打包后的动态加载故障
解决MSIX打包后MEF加载部件失败(找不到密钥文件)的问题
问题分析
MSIX包的安装目录属于受保护的系统路径,AppDomain.CurrentDomain.BaseDirectory在MSIX环境下可能指向非预期位置,同时MEF加载部件时触发的“找不到密钥文件”错误,可能和程序集加载权限、路径错误,或是目标部件的静态初始化逻辑有关。
解决方案
1. 替换为MSIX专属的安装目录路径
MSIX应用的安装目录需通过Windows SDK提供的API获取,替换原有的目录路径:
using Windows.ApplicationModel; using System.IO; private void Initialized() { var catalog = new AggregateCatalog(); // 获取MSIX包的实际安装目录 var installPath = Package.Current.InstalledLocation.Path; catalog.Catalogs.Add(new DirectoryCatalog(installPath)); m_Container = new CompositionContainer(catalog); this.m_Container.ComposeParts(this); // 后续遍历逻辑... }
注意:桌面应用需引用Microsoft.Windows.SDK.Contracts NuGet包以使用Windows.ApplicationModel.Package API。
2. 验证程序集打包配置与签名
- 确认服务DLL已正确添加到打包项目:在Windows应用打包项目的“文件”选项卡中,检查DLL是否已包含,且生成操作设为
内容,复制到输出目录设为始终复制。 - 若DLL为强签名,尝试临时移除签名测试,排查是否因密钥文件未被正确打包导致加载失败。
3. 直接加载指定程序集(替代目录扫描)
避免目录扫描的不确定性,直接加载目标服务程序集:
using Windows.ApplicationModel; using System.Reflection; using System.IO; private void Initialized() { var catalog = new AggregateCatalog(); var installPath = Package.Current.InstalledLocation.Path; var assemblyPath = Path.Combine(installPath, "People.dll"); var peopleAssembly = Assembly.LoadFrom(assemblyPath); catalog.Catalogs.Add(new AssemblyCatalog(peopleAssembly)); m_Container = new CompositionContainer(catalog); this.m_Container.ComposeParts(this); // 后续遍历逻辑... }
4. 排查部件的静态初始化逻辑
错误日志明确提到People的类型初始值设定项引发异常,需检查:
People类的静态构造函数、静态字段初始化逻辑,是否存在访问受保护文件、路径的操作(MSIX环境下应用无法随意访问系统目录)。- 将静态初始化逻辑迁移至实例构造函数,避免在类型加载阶段触发权限或路径错误。
内容的提问来源于stack exchange,提问作者B. Bram
相关产品推荐
相关产品推荐

