2

我正在为我正在处理的项目创建两个解决方案,一个用于主服务器,理想情况下它将持续运行而无需更新。第二种解决方案是 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(在运行时,无需重建)证明是困难的。

4

1 回答 1

0

对于面临同样问题的任何人,我都可以使用动态编译器。查看 CSharpCodeProvider 和 CSharpCodeProvider.CompileAssemblyFromFile。这是我需要的一切。

于 2013-03-24T16:15:33.353 回答