2016-02-26 18 views
1

我剛剛遇到了一個我之前沒有見過的程序集引用的問題。在我通常的生產代碼中,我的加載器應用程序通過將原始字節傳遞到Assembly.Load然後調用入口點來加載主應用程序集(和其他引用)。手動加載程序集時丟失了組件交叉引用

今天我需要讓主應用程序動態加載另一個引用(以後稱爲'dll'),它包含一個從主程序中的基類繼承而來的類。這在直接運行主應用程序時可以正常工作。當它通過加載器運行時,主應用程序加載dll就好了,但似乎並不知道當前加載的主應用程序與dll引用的應用程序相同。所以鑄造到基類顯然是行不通的。我被卡住了。

我假設主應用程序集會以某種方式失去它的身份。

下面是一些代碼,說明了問題:

// main application 
namespace Program1 
{ 
    public class BaseClass { } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      string s = "Library1.Class1, Library1";    
      var t = Type.GetType(s, true); 
      Debug.Assert(t.IsSubclassOf(typeof(BaseClass))); 
     } 
    }  
} 

// dll 
namespace Library1 
{ 
    public class Class1 : Program1.BaseClass { } 
} 

// loader 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var bytes = File.ReadAllBytes("Program1.exe"); 
     var asm = Assembly.Load(bytes); 
     var e = asm.EntryPoint; 
     e.Invoke(null, new object[] { null }); 
    } 
} 

運行時直接PROGRAM1它的工作原理,通過斷言失敗加載器運行時。

那麼,有人能解釋這裏發生了什麼 - 如果有可能的解決辦法嗎?

+0

你檢查了Fusion日誌嗎? –

+0

@JfBeaulac沒有發生在我身上,但是如果我做到了,我肯定會看到它會加載一個程序集兩次! – Chris

回答

1

如果(我們稱之爲DLLA和dllB你的庫),DLLA具有dllB參考,並加載DLLA的,它不會崩潰,也意味着.NET已經autoresolved並加載dllB。

然後,當你再次加載dllB它是另一個程序集,然後類型不匹配,我用dll加載系統在這種情況下跑了很多次,最後最好添加引用的庫(在本例中爲dllB)放在.exe文件夾中,讓系統在加載dllA時自動加載它。

如果您需要引用庫的另一個選項是在加載DllA之前附加到AssemblyResolve事件,那麼當您加載它時,事件將觸發,要求您加載DllB,因此可以將引用存儲到庫中。

+0

AssemblyResolve:https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve%28v=vs.110%29.aspx – Gusman

+0

啊,地獄,現在看起來很明顯。沒想到,顯然該DLL會加載它自己需要的東西。所有非常有趣的,因爲在生產中我已經使用AssemblyResolve來加載已更改文件名(因此不能自動解決)的加密程序集,所以如果我在生產中運行它,它會工作。但現在我用它來找到所有的文件。感謝一羣人。 – Chris

+0

呵呵呵,那個錯誤是一種痛苦,直到你找到它造成它的原因,那是一個omfg時刻.. XD – Gusman

相關問題