如何在没有程序重启的情况下更新dll文件?
我想创建我的"更新程序"类。它的主要思想是 检查本地(连接到执行文件)和服务器DLL文件, 当有更新的版本时,将服务器文件复制到本地。
代码:
Updater updater = new Updater(LOCAL_PATH, SERVER_PATH);
if (updater.IsAvailableNewerVersion)
updater.Update();
更新程序的ctor采用两条路径 - 服务器dll和本地dll并计算其版本。 然后我调用一个属性IsAvailableNewerVersion - 如果它是真的(可用版本比本地更新),我调用Update方法。 更新方法的主要思想是将服务器dll文件复制到本地并覆盖,并告诉用户重启程序。
代码:
public class Updater
{
private readonly string _localPath;
private readonly string _serverPath;
private readonly Version _currentVersion;
private readonly Version _availableVersion;
public Updater(string localPath, string serverPath)
{
_localPath = localPath;
_serverPath = serverPath;
_currentVersion = AssemblyName.GetAssemblyName(_localPath).Version;
_availableVersion = AssemblyName.GetAssemblyName(_serverPath).Version;
}
public bool IsAvailableNewerVersion => _availableVersion.Major > _currentVersion.Major ||
_availableVersion.MajorRevision > _currentVersion.MajorRevision ||
_availableVersion.Minor > _currentVersion.Minor ||
_availableVersion.MinorRevision > _currentVersion.MinorRevision ||
_availableVersion.Build > _currentVersion.Build ||
_availableVersion.Revision > _currentVersion.Revision;
public void Update()
{
try
{
File.Copy(_serverPath, _localPath, true);
}
catch (Exception e)
{
MessageBox.Show("Unable to copying file - " + e);
return;
}
MessageBox.Show("File was successfully updated. Please restart program.");
}
}
P.S。 我认为使用服务器DLL文件,但我的程序依赖于服务器不好。
答案 0 :(得分:3)
您无法在正在运行的应用程序域中卸载/更改程序集;所以基本上你有两个选择:
第二种方法对服务器应用程序更有用,因为您可以将外部exe和漏斗请求中的网络IO处理到内部app-domain,只需将单个引用更改为两个系统之间的交换。但是,app-domains不在.NET Core中,因此您应该意识到它限制了您的灵活性。
答案 1 :(得分:0)
<强> 1。有没有办法在使用之前检查dll文件?
如果您使用单个EXE,则取决于您使用DLL的方式。如果它们与您的应用程序紧密耦合,我不知道如何这样做。
但是如果DLL只是实现核心DLL的接口,你可以使用以下命令加载它们:
Assembly assembly = Assembly.LoadFrom("path\orbital.dll"));
Type type = assembly.GetType("FullClassName");
object instanceOfMyType = Activator.CreateInstance(type);
这要求您遵循一些设计模式,这对您的应用程序有利。但是,如果您已经有多个强耦合的DLL(这意味着,您在Visual Studio项目中将它们添加为引用并且正在创建var object = new YourOtherDLLNamespace.YorObjectInTheOtherDLL()
对象),那么您可能需要花费大量时间来更改此方法。 / p>
这种方法的好处是你可以在加载之前检查DLL版本,从服务器复制新版本(或你认为合适的任何其他方法),然后加载它。
<强> 2。如何在没有程序重启的情况下更新dll文件?
好吧,假设你就像我对第1项的建议一样。一旦你加载了DLL,你将无法卸载它。您可以使用垃圾收集器销毁所有对象,但这不会改变窗口加载它的方式。
所以单个EXE的基本答案是否定的。
其他解决方案
你可以将你的解决方案包装在不断检查DLL是否更新的其他EXE中,发送一个自定义事件(这样你的应用程序EXE现在会在关闭它之前采取适当的行动),通知用户并且,如果用户想要这样做,那么您可以关闭该应用程序。然后你的其他app包装器会更新它并再次启动EXE。