簡體   English   中英

如何在緊湊框架中從字節數組加載程序集

[英]How to load an assembly from byte array in compact framework

我有遺留客戶使用智能掃描儀和舊的Windows移動設備。 結果,我在這些智能設備的緊湊框架中陷入困境。 我正在編寫一個類庫,它將為掃描儀硬件的接口提供插件類型機制。 我希望能夠將來自掃描儀制造商的第三方程序集嵌入到插件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接口等,需要在使用前先注冊。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM