2011-09-09 14 views
4

我的任務:在dll或exe文件中查找所有窗體(WindowsForm或WPF,無所謂)並返回該列表。在理論上這是有效的(意思是說:如果我有一個WPF或WindowsForm的程序集,我的代碼設法獲取所有的表單,文本框,標籤等)。當涉及到「真實」的組件時,它會失敗。爲每個「自定義」程序集調用GetExportedTypes()時會發生FileNotFound異常(找到.NET程序集,這裏沒有問題)。我已經使用GetReferencedAssemblies()加載引用的程序集(Reflection.Assembly.LoadFrom),並且它確實有效(所有程序集均已找到並加載到AppDomain中),但它無濟於事。GetExportedTypes()FileNotFoundException:無法找到彙編

我檢查了版本號(它們匹配),我將我的可執行文件和程序集複製到一個包含所有引用程序集的目錄中,不起作用。

這裏是我的代碼,也許有人計算出什麼我(顯然)做錯了:

foreach (AssemblyName reference in selectedAssembly.GetReferencedAssemblies()) 
{ 
     if (System.IO.File.Exists(
      System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
       @"\" + reference.Name + ".dll")) 
     { 
     System.Reflection.Assembly.LoadFrom(
      System.IO.Path.GetDirectoryName(selectedAssembly.Location) + 
       @"\" + reference.Name + ".dll"); 
     } 
     else if (System.IO.File.Exists(@"C:\dll\" + reference.Name + ".dll")) 
     { 
     System.Reflection.Assembly.LoadFrom(@"C:\dll\" + reference.Name + ".dll"); 
     } 
     else 
     { 
     System.Reflection.Assembly.ReflectionOnlyLoad(reference.FullName); 
     } 

     selectedAssembly.GetExportedTypes();  
} 

首先檢查一下在該組件的目錄中存在的參考DLL,如果不檢查它存在於C:\ dll中,如果它不存在,請嘗試使用GAC。它工作,我從那裏沒有任何錯誤,但只要我來GetExportedTypes它失敗,第一個自定義庫上的FileNotFound異常。

*編輯1這是什麼意思是「真正的組件」:我的意思是組件這是更復雜,必須non-standard-.NET庫/組件

引用

感謝提示fuslogvw .exe漢斯帕贊特,但你是什麼意思的「這樣的代碼」?


還好我用fuslogvw.exe,我得到了一個由「selectedAssembly」中引用的每一單個DLL兩個例外。 第一個說像

其他logentry說,由selectedAssembly引用的DLL不能「在LoadFrom上下文 屬於系統的圖像不在LoadFrom - 語境搜索的結合開始」被發現,它試圖從應用程序的基本路徑和下面的所有目錄下載...但不是從它的實際位置...所以,關鍵問題:如何將Load-context更改爲LoadFrom?爲什麼.NET很固執呢?我的意思是程序集加載到AppDomain中,它不應該關心程序集的實際位置。


好的問題解決了。這裏是解決方案: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

我實施了到我現有的類(去除靜態關鍵字,並把Init方法的身體進入我的方法),編譯它和它的工作。

感謝您的幫助球員。

+0

你所說的「真正的組件」 –

+3

使用fuslogvw.exe解決此指的是源代碼。它向您顯示哪些綁定失敗,包括依賴程序集的綁定。像這樣的代碼常見的問題。 –

回答

3

好的問題解決了。這裏是解決方案:http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

我將它實現到我現有的類中(刪除了static-關鍵字並將Init方法的主體放入我的方法中),編譯並工作。

感謝您的幫助球員。

以防萬一網站總有一天會無法使用,這裏是從ayende

static Dictionary<string, Assembly>assemblies; 

public static void Init() 
{ 

    assemblies = new Dictionary<string, Assembly>(); 

    AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad); 

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
} 

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 

    Assembly assembly = null; 

    assemblies.TryGetValue(args.Name, out assembly); 

    return assembly; 

} 

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args) 
{ 

    Assembly assembly = args.LoadedAssembly; 
    assemblies[assembly.FullName] = assembly; 
} 
2

我會推薦使用Reflector來查看哪些引用可能沒有加載。例如,您只加載當前程序集正在查看的引用程序集。你是否會逐個介紹每個孩子以找到他們引用的程序集? FileNotFound錯誤可能指向您在另一個未加載的程序集中聲明的類型的方向。

+0

嗯,謝謝你。我將重建該foreach循環作爲遞歸循環。但這真的可以成爲問題嗎?我的意思是程序集加載到AppDomain中時沒有錯誤,我只在選定的程序集上調用「GetExportedTypes」,而不是在所有其他程序集上。 –

+0

對不起,這不是問題。 LoadContext是問題;)。 –

相關問題