【问题标题】:How to update dll-file without main program being restart?如何在不重新启动主程序的情况下更新 dll 文件?
【发布时间】:2018-01-31 09:16:39
【问题描述】:

如何在不重新启动程序的情况下更新 dll 文件?

我想创建我的“更新程序”类。它的主要思想是 检查本地(连接到执行文件)和服务器 dll 文件, 当有新版本可用时,将服务器文件复制到本地。

代码:

Updater updater = new Updater(LOCAL_PATH, SERVER_PATH);
if (updater.IsAvailableNewerVersion)
    updater.Update();

更新程序的 ctor 采用两条路径 - 到服务器 dll 和本地 dll 并计算它们的版本。 然后我调用一个属性 IsAvailableNewerVersion - 如果它是真的(可用版本比本地更新),我调用 Update 方法。 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.");
    }
}
  1. 有没有办法在使用 dll 文件之前对其进行检查?
  2. 如何在不重新启动程序的情况下更新 dll 文件?

附言 我想使用服务器 dll 文件,但我的程序变得依赖于不好的服务器。

【问题讨论】:

    标签: c# .net dll


    【解决方案1】:

    您不能真正卸载/更改正在运行的应用程序域中的程序集;所以基本上你有两个选择:

    1. 使用启动器 exe 来完成这项工作并调用 inner exe 来完成真正的工作,完成后将其关闭(在关闭之前或之后启动一个新的)
    2. 在单个 exe 中使用多个应用程序域,隔离每个应用程序的加载位置

    第二种方法对服务器应用程序更有用,因为您可以在外部 exe 中处理网络 IO,并将请求集中到内部应用程序域,只需更改单个引用以在两个系统之间进行交换。但是,应用程序域不在 .NET Core 中,因此您应该注意它会限制您的灵活性。

    【讨论】:

      【解决方案2】:

      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()),那么您可能需要花费大量时间来更改此方法。

      这种方法的好处是您可以在加载之前检查 DLL 版本,从服务器(或您认为合适的任何其他方法)复制新版本,然后加载它。

      2。如何在不重启程序的情况下更新 dll 文件?

      好的,假设您按照我对第 1 项的建议进行了操作。加载 DLL 后,您将无法卸载它。您可以使用垃圾收集器销毁所有对象,但这不会改变 windows 加载它的方式。

      所以单个 EXE 的基本答案是否定的。

      其他解决方案

      您可以将您的解决方案包装在其他不断检查 DLL 是否更新的 EXE 中,发送自定义事件(以便您的应用程序 EXE 现在可以在关闭之前采取适当的操作),通知用户而且,如果用户想要这样做,那么您可以关闭该应用程序。然后您的其他应用程序包装器将对其进行更新并再次启动 EXE。

      【讨论】:

        猜你喜欢
        • 2020-02-15
        • 2021-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-06
        • 1970-01-01
        相关资源
        最近更新 更多