2015-10-05 62 views
3

我已經搜查了地獄,這一點,但我不能完全弄清楚爲什麼我得到一個FileNotFoundException異常時,該文件明確存在,並且可以與File.ReadAllBytes如何將此程序集加載到我的AppDomain中?

這是我當前的代碼打開:

AppDomainSetup domainInfo = new AppDomainSetup(); 
domainInfo.ApplicationBase = PluginDirectory; 
Evidence adEvidence = AppDomain.CurrentDomain.Evidence; 
AppDomain pluginDomain = AppDomain.CreateDomain("pluginDomain", adEvidence, domainInfo); 

foreach (FileInfo file in files) 
{ 
    if (m_AssemblyIgnoreList.Contains(file.Name)) 
     continue; 

    byte[] assemblyBytes = File.ReadAllBytes(file.FullName); 
    //Assembly plugin = Assembly.LoadFrom(file.FullName); 

    Assembly plugin = pluginDomain.Load(assemblyBytes); 

    LoadPlayerEvents(plugin); 
} 

AppDomain.Unload(pluginDomain); 

我試圖從一個插件文件夾中加載所有.dll文件,並加載一堆屬性類型和函數。

當我使用Assembly.LoadFrom(file.FullName)時,加載屬性類型和函數的工作文件。然而,pluginDomain.Load(assemblyBytes)導致了以下異常:

FileNotFoundException: Could not load file or assembly 'Example Mod, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. 

它肯定找到指定的文件,因爲File.ReadAllBytes完美的作品,作爲異常顯示我試圖加載程序集的全名。因此我得出結論:它不能加載依賴項。

所有的依賴項已經加載到CurrentDomain中。雖然,即使將這些依賴關係置於.dll旁邊(這發生在所有.dll的生成過程中),也會產生相同的異常。

爲什麼我得到這個異常,當文件明顯存在?

+0

您可以運行[進程監視器(https://technet.microsoft.com/en-us/sysinternals/bb896645 .aspx)來檢查應用程序在哪些位置搜索DLL,也許你會明白爲什麼它不在你想要的位置搜索。 – Oliver

回答

1

您應該加載當前域中的AssemblyResolve事件處理程序的組件,如解釋here

+0

我想不使用Assembly.Load,因爲它保持使用dll文件,直到appdomain被卸載。我希望能夠在加載所有插件後立即卸載appdomain,並且我需要的每個方法的MethodInfo變量都已存儲在列表中。這樣我可以在之後調用這些方法。 – TristenHorton

+0

是的,但dll將被加載到新創建的域,所以一旦它被卸載,dll將被釋放。也許我寫錯了:通過「當前」域,我的意思是你剛剛創建的域。請注意,AppDomain.Load和事件處理程序都是靜態的,因此稱爲新創建的域。來自示例的解決方案應該適合您的目的。告訴我你是否需要代碼示例。 – h3rb4l

+0

我剛剛注意到,你寫了你想要後來調用方法..這是不可能的,因爲他們加載到的域,卸載。您需要將dll加載到某個域中才能使用它們。你可以動態地做到這一點,通過創建一個單獨的域並按需加載必要的DLL,但恐怕這不會有效。你究竟想在這裏完成什麼? 另外,通過將MethodInfo變量存儲在基本變量中來引用這兩個域,可能會阻止卸載。你需要找到一個不同的解決方案。 – h3rb4l

相關問題