我正在为我正在处理的项目创建两个解决方案,一个用于主服务器,理想情况下,无需更新即可连续运行。辅助解决方案是DLL,程序员将不断更改和更新代码。服务器解决方案是一个Windows应用程序,程序员的解决方案(不断变化的,AKA JupiterCode.dll)是一个类库。
我通过telnet访问代码,这是必需的,并将在那里输入命令。然后输入字符串将通过DLL文件上的反射执行(“用户输入'微笑'。是否有一个名为'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'或其依赖项之一。给定的程序集名称或代码库是无效。(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,Version = 1.0.0.0, Culture = neutral,PublicKeyToken = 9a98a67e4d0b3db8'或其中一个 依赖。系统找不到该文件 指定。“:”JupiterCode,Version = 1.0.0.0,Culture = neutral, 公钥= 9a98a67e4d0b3db8"
同样,重申一下,我能够在运行时动态加载程序集,但是用更新的程序替换加载的DLL(在运行时,没有重建)是很困难的。
答案 0 :(得分:0)
对于遇到同样问题的人,我能够使用动态编译器。查看CSharpCodeProvider和CSharpCodeProvider.CompileAssemblyFromFile。这就是我需要的一切。