2013-03-23 81 views
2

我正在爲我正在開發的一個項目創建兩個解決方案,一個用於主服務器,它將在不需要更新的情況下持續運行。次要解決方案是DLL,程序員將不斷更改和更新代碼。服務器解決方案是一個Windows應用程序和程序員的解決方案(一個不斷變化的,AKA JupiterCode.dll)是一個類庫。動態更新加載的DLL

我通過telnet訪問代碼,這是必需的,並將在那裏輸入命令。然後輸入的字符串將通過DLL文件上的反射來執行(「用戶輸入'smile',是否有命令叫做'smile'?是的,我們來執行這個代碼吧。」)。我已經完成了所有這些工作,並且正在順利進行,但是當我想要實際更新DLL時,我遇到了一些問題,以便用戶可以輸入更多命令。當我重建類庫時,服務器尚未反映新的更改。服務器只在我重建服務器時反映新的更改。

我想這樣當用戶進入UPDATE到telnet服務器擁有它,它會更新新的DLL加載的DLL,但是當我嘗試做這樣的事情......

 string originalDllPath = "C:\\Users\\*****\\Documents\\PseudoGameClient\\bin\\Debug\\JupiterCode.dll"; 
string newDllPath = "C:\\Users\\*****\\Documents\\PseudoServerStub\\bin\\Debug\\.dll"; 
string newDllBakPath = "C:\\Users\\*****\\Documents\\PseudoServerStub\\bin\\Debug\\JupiterCodeNewBak.dll"; 
string oldDllPath = "C:\\Users\\*****\\Documents\\PseudoServerStub\\bin\\Debug\\JupiterCode.dll"; 
string oldDllBakPath = "C:\\Users\\*****\\Documents\\PseudoServerStub\\bin\\Debug\\JupiterCodeBak.dll"; 

try 
{ 
File.Copy(originalDllPath, newDllPath, true); 

AppDomain.Unload(updatedCodeDomain); 
AppDomain sandbox = AppDomain.CreateDomain("Sandbox"); 
Assembly assembly = sandbox.Load(oldDllBakPath); 
upToDateCode = assembly; 
File.Copy(oldDllPath, newDllBakPath, true); 
File.Copy(newDllPath, oldDllPath, true); 

AppDomain.Unload(sandbox); 
AppDomain newCodeDomain = AppDomain.CreateDomain("NewCode"); 
assembly = newCodeDomain.Load(oldDllPath); 
upToDateCode = assembly; 
File.Copy(newDllBakPath, oldDllBakPath, true); 

File.Delete(newDllPath); 
File.Delete(newDllBakPath); 
updatedCodeDomain = newCodeDomain; 
} 
catch (Exception ex) 
{ 
} 

在這種方法中,一旦它到達

Assembly assembly = sandbox.Load(oldDllBakPath);

這讓我異常:

「無法加載文件或程序集」C:\\ Users \\ aderbedrosia \\ Documents \\ PseudoServerStub \\ bin \\ Debug \\ JupiterCodeBak.dll「或其某個依賴項。給定的程序集名稱或代碼庫無效。 (Exception from HRESULT:0x80131047)「:」C:\\ Users \\ aderbedrosia \\ Documents \\ PseudoServerStub \\ bin \\ Debug \\ JupiterCodeBak.dll「} System.Exception {System.IO.FileLoadException

(注意:Uptodatecode保留爲一個類字段,因爲我後面指的是它執行的命令,它再次,工作完好,除了無法更新。)

我也嘗試過:

File.Copy(originalDllPath, newDllPath, true); 
Assembly assembly = Assembly.LoadFrom(oldDllBakPath); 
AppDomain.Unload(updatedCodeDomain); 

AppDomain sandbox = AppDomain.CreateDomain("sandbox"); 
sandbox.Load(assembly.GetName()); 
upToDateCode = null; 
upToDateCode = assembly; 
File.Copy(oldDllPath, newDllBakPath, true); 
File.Copy(newDllPath, oldDllPath, true); 
assembly = Assembly.LoadFrom(oldDllPath); 
AppDomain.Unload(sandbox); 

AppDomain sandbox2 = AppDomain.CreateDomain("secondarySandbox"); 
sandbox2.Load(assembly.GetName()); 
upToDateCode = assembly; 
File.Copy(newDllBakPath, oldDllBakPath, true); 
File.Delete(newDllPath); 
File.Delete(newDllBakPath); 
updatedCodeDomain = sandbox2; 

,並在

錯誤出
sandbox.Load(assembly.GetName()); 

「無法加載文件或程序集 'JupiterCode,版本= 1.0.0.0, 文化=中性公鑰= 9a98a67e4d0b3db8' 或它 的一個依賴。系統無法找到文件指定 「:」 JupiterCode,版本= 1.0.0.0,文化=中立, 公鑰= 9a98a67e4d0b3db8"

再次重申,我能夠在運行時動態加載程序集,但用一個更新的DLL替換一個更新的DLL(在運行時,不需要重新編譯)是很困難的。

回答

0

對於任何面臨同樣問題的人,我都可以使用動態編譯器,查看CSharpCodeProvider和CSharpCodeProvider.CompileAssemblyFromFile。這是我需要的一切。