2015-04-02 21 views
3

我有旧式客户端,他们使用智能扫描仪和旧版Windows Mobile。因此,我坚持在这些智能设备的紧凑框架中开发。我正在编写一个类库,它将为扫描器硬件的接口提供插件类型机制。我希望能够将来自扫描仪制造商的第三方程序集作为嵌入式资源嵌入到插件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)); 
       } 
      } 
     } 
    } 

回答

2

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

2

由于几个原因,我不建议将供应商组件嵌入到您的组件中。首先,并非所有设备供应商的SDK都是可以或应该放在应用程序文件夹中的纯.NET。许多人需要运行它们的安装来将标准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创建时间,包括信息动态加载它们基于一个配置文件或其他命名惯例。该应用程序确实知道或关心抽象的哪个实现被加载,只是它符合抽象。

0

我看到了两个可能的解决方案,从一个应用程序支持不同的设备:

  1. 你用你的方法和使嵌入设备的需要的组件上,System.Reflection.Assembly.LoadAssembly(字节[] )不受支持,首先将程序集保存到文件系统,然后加载它。这样你就可以对所有不同的运行时文件进行大量的应用,只需要保存所需的运行时并从文件系统加载/运行。

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

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

有关如何使用PocketMEF硬件abstracion的文章是在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条码扫描器.NET程序集需要本地DLL itcscan.dll)。有时这些预安装在windows mobile/CE设备上,有时需要先安装它们。安装可能意味着仅复制DLL或(我不知道使用该DLL的供应商),安装额外的COM接口等,需要在使用之前先注册。

相关问题