如何在紧凑框架中从字节数组加载程序集

我有遗留客户使用智能扫描仪和旧手机。 结果,我不得不在这些智能设备的紧凑框架中开发。 我正在编写一个类库,它将为扫描仪硬件的接口提供插件类型机制。 我希望能够将来自扫描仪制造商的第三方程序集作为插件DLL中的嵌入式资源嵌入。 我想这样做是为了避免在我的插件系统试图找到插件接口的实现时必须反映所有第三方DLL。 漂亮的海峡前进。 问题是,使用嵌入式资源,我可以获得程序集的字节,但System.Reflection.Assembly.LoadAssembly(byte[])在紧凑框架中不可用。 只有LoadAssembly(AssemblyName)LoadAssembly(String) 。 如何在运行时从嵌入式资源加载这些程序集?

这就是我现在拥有的:

  protected void LoadEmbeddedAssemblies() { Assembly asm = Assembly.GetCallingAssembly(); foreach (string resName in asm.GetManifestResourceNames()) { if (resName.EndsWith(".dll")) { try { //this is an embedded assembly using (Stream s = asm.GetManifestResourceStream(resName)) { if (s.Length > Int32.MaxValue) throw new IOException("The assembly is to large"); byte[] bytes = new byte[s.Length]; s.Read(bytes, 0, Convert.ToInt32(s.Length)); //Assembly.Load(bytes) <- Compact Framework sucks } } catch (Exception e) { Log(new LogMessageRaisedEventArgs("AScannerBase", "LoadEmbeddedAssemblies", "Exception encountered while loading embedded assembly", e.Message)); } } } } 

Compact Framework不支持以这种方式加载程序集。 由于应用程序运行的平台不太可能在给定设备上发生变化,只需确定第一次运行的设备类型并将适当的程序集提取到app文件夹,从那时起,加载程序就会找到它们。

出于几个原因,我不建议将供应商程序集嵌入您的程序集中。 首先,并非所有设备供应商SDK都是纯.NET,可以或应该在app文件夹中填充。 许多需要运行它们的安装来放置标准dll,注册表项等。 其次,通过将每个供应商程序集嵌入到中间件中来增加组件的大小,假设您支持多个供应商,则大小可能会变得非常大。 特别是如果设备已经在GAC中具有扫描组件,则您将获得根本不需要的额外存储。

我使用并建议以下机制:

 Application(s)...................................... | . V . Generic scanning abstraction lib . (Assembly.LoadFrom based A . upon convention or XML | . configuration file) Vendor Specific Implementation of abstraction <..... | V Vendor SDK 

通过这种方式,您可以在CAB创建时设置“插件”,包括根据配置文件或其他命名约定动态加载它们的信息。 应用程序确实知道或关心抽象的哪个实现被加载,只是它符合抽象。

我看到两种可能的解决方案来支持一个应用程序中的不同设

  1. 您使用您的方法并嵌入所需的设备程序集,并且不支持System.Reflection.Assembly.LoadAssembly(byte []),首先将程序集保存到文件系统,然后加载它。 这样你就拥有了一个包含各种不同运行时文件的大型应用程序,其中只保存所需的运行时并加载到文件系统或从文件系统加载。

  2. 您使用像PocketMEF这样的插件系统,并具有不同的子目录来加载供应商特定的程序集和本机DLL。 根据供应商的不同,可以动态加载朗读时间。

在这两种情况下,您都必须定义一个接口层并实现为不同供应商的SDK实现接口的类。

有关如何使用PocketMEF进行硬件抽象的文章, 请访问http://www.hjgode.de/wp/2012/02/16/mobile-development-compact-framework-managed-extension-framework-mef/

使用pocketMEF的几个接口的另一个例子是https://github.com/hjgode/intermeccontrols/blob/master/DPAG7

并且,cTacke是正确的,大多数.NET供应商组件需要额外的本机库(即Intermec Barcode Scanner .NET程序集需要本机DLL itcscan.dll)。 有时这些预先安装在Windows mobile / CE设备上,有时需要先安装它们。 安装可能意味着仅复制DLL或(我不知道使用它的供应商),安装额外的COM接口等,需要在使用前先注册。