我正在为我正在处理的项目创建两个解决方案,一个用于主服务器,理想情况下它将持续运行而无需更新。第二种解决方案是 DLL,程序员将在其中不断更改和更新代码。服务器解决方案是一个 Windows 应用程序,而程序员的解决方案(不断变化的,AKA JupiterCode.dll)是一个类库。
我正在通过 telnet 访问代码,这是必需的,并且将在那里输入命令。然后将通过 DLL 文件上的反射执行输入字符串(“用户输入了 'smile'。是否有一个名为 'smile' 的命令?是的,好的,让我们执行该代码。”)。我已经完成了所有这些工作,并且运行顺利,但是当我想实际更新 DLL 以便用户可以输入更多命令时,我遇到了障碍。当我重建类库时,服务器还没有反映新的变化。服务器仅在我重建服务器时反映新的更改。
我正在尝试拥有它,因此当用户在 telnet 服务器中输入 UPDATE 时,它将使用新的 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 =中性,PublicKeyToken=9a98a67e4d0b3db8"
再次重申,我能够在运行时动态加载程序集,但是用更新的 DLL 替换加载的 DLL(在运行时,无需重建)证明是困难的。