• 【WPF】软件更新程序的设计思路


    目标:客户端程序在启动时,自动联网检查服务端是否有新的版本,有则提示用户更新客户端。

    思路:

    1、打开Visual Studio,在主体程序的解决方案下再新建一个叫自动更新程序的项目。主体程序的目录是D:workspaceMyProjectClient自动更新程序的目录是D:workspaceMyProjectUpdateTool

    2、最后打包出来时将两个项目合并在一个Debug文件中。只需把自更程序exe和它依赖的dll文件一并拷到主体程序打包出来的Debug文件夹下即可。此时Debug文件夹下会有两个exe(自更程序UpdateTool.exe和主体程序Client.exe),如果从自更程序exe启动,就先检查版本再启动主体程序;如果从主体程序exe启动,就跳过了检查版本。具体看个人需求,比如不想让用户继续用旧版本的主体程序,强制要求用户从自更程序exe启动的话,也可以隐藏或者通过重命名主体程序exe的方式不让用户能点击,再在自更程序中启动主体程序。

    2、VS编辑器中将自动更新程序设为软件启动项(开发完自更程序后再切回去即可,因为在开发阶段不希望每次启动都先运行自更程序嘛)。新建一个Program类写上Main()函数作为项目运行入口。启动项目时,执行自动更新程序的Main()函数,先检查自动更新程序其自身是否需要更新!检查自更程序编译出来Debug文件夹下的exe文件的版本号如下。

    FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(System.Windows.Forms.Application.ExecutablePath); // ExecutablePath = D:workspaceMyProjectUpdateToolinDebugUpdateTool.exe
    string fileVersions = string.Format("{0}.{1}.{2}.{3}", fileVersionInfo.FileMajorPart, fileVersionInfo.FileMinorPart, fileVersionInfo.FileBuildPart, fileVersionInfo.FilePrivatePart);
    

    3、自更程序的Main()函数通过传参判断是否其自身是否需要更新。有就下载更新,没有就不更新。

    4、传递自更程序的版本到服务端,服务端查数据库获取最新版本号(最大版本号 SELECT max(version) FROM update_tool_version),发现当前自更程序不是最新版本,返回最新版本还需下载的文件压缩包的url路径。该压缩包内的文件是新的图片资源、新版本自更程序exe等。

    5、现假设要求先更新自更程序。自更程序的增量内容压缩包下载到本地的缓存文件夹下。现获取该文件夹路径如下。

    string cachePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\MyProject"; // C:\Users\Administrator\AppData\Roaming\MyProject
    DirectoryInfo directoryInfo = new DirectoryInfo(cachePath);
    if (!directoryInfo.Exists)
    {
        directoryInfo.Create(); // 目标文件夹不存在就创建
    }

    6、由于当前的自更程序exe已处于运行状态,该exe文件被占用了,升级包中的UpdateTool.exe是无法覆盖这个文件的,所以采取的办法是将UpdateTool.exe拷贝到缓存文件夹中,然后启动缓存文件夹中的UpdateTool.exe文件来完成升级的过程。

    把自更程序exe复制到缓存文件夹,再传参启动副本exe,并关闭当前的exe。自更程序在Main()函数中通过判断传入的参数,执行下载新版本的逻辑,覆盖项目路径下的UpdateTool.exe。

    // 先把当前自更程序exe文件考到缓存文件夹中
    Process processes = Process.GetCurrentProcess();
    string name = processes.ProcessName;
    string source = System.Windows.Forms.Application.StartupPath + "\" + name + ".exe"; // D:workspaceMyProjectUpdateToolinDebugUpdateTool.exe
    string target = cachePath + "\" + name + ".exe"; // C:\UsersAdministratorAppDataRoamingmjlUpdateTool.exe
    File.Copy(source, target, true);
    string arg = System.Windows.Forms.Application.StartupPath; // D:workspaceMyProjectUpdateToolinDebug
    if (!string.IsNullOrEmpty(updateUrl))
    {
        arg += ("|" + updateUrl); // D:workspaceMyProjectUpdateToolinDebug|/assets/file/1518053629860.zip
    }
    arg = """ + arg + """; // "D:workspaceMyProjectUpdateToolinDebug|/assets/file/1518053629860.zip"
    
    // 传参运行副本自更程序exe,Main()函数通过传参执行下载新版本的逻辑
    ProcessStartInfo info = new ProcessStartInfo(target, arg); 
    Process.Start(info);
    
    // 关闭当前的自更程序
    Environment.Exit(0);

     7、上面的操作再次启动自更程序exe时,由于这次Main()函数有传参,所以执行下载新版本的操作。

    // 开始更新自更程序
    App app = new App();
    UpdateToolView view = new UpdateToolView(args[0]);
    app.Run(view); // 触发UpdateToolView.xaml.cs的构造方法

    8、更新自更程序的界面UpdateToolView是一个很简单的窗体,只有一个ProgressBar进度条展示更新的进度。UpdateToolView的构造方法中通过传入的args获取到UpdateTool项目路径和更新文件的url地址后,用BackgroundWorker类开一个后台线程进行文件下载,边下载边更新ProgressBar进度条。

    9、下载完成后,解压缩到UpdateTool项目路径下。解压工具类可使用第三方库ICSharpCode.SharpZipLib.Zip.dll,网上能搜到很多例子,如这里

    10、完成解压后,不传参启动该新版本exe,同时退出当前旧版本的自更程序。自此,就已完成更新自更程序到最新版本了。

    ______ 休息一下 ______

    11、上一步不传参启动了自更程序后,自更程序Main()函数就不再检查自更程序的版本,开始检查主体程序的版本。流程跟上面更新自更程序的步骤几乎一致。

    12、如果主体程序已经是最新版本,则直接启动主体程序并关闭自更程序。

    13、如果主体程序也需要更新,下载、解压逻辑与上面相似。重下客户端可能压缩包会比较大,可先下载到缓存文件夹Roming下再解压到项目目录中。如果是增量更新(压缩包的内容是新增的图片资源、新增大dll文件等)就不用考虑解压后项目文件夹重名的问题。

    注意:更新主体程序除了要更新Client.exe还要更新配置文件Client.exe.config!如果不能同名覆盖的话就要先删除本地旧的config再解压压缩包!

    14、解压完成后,闭残留的主体程序进程,启动主体程序。

    // 关闭残留的主体程序的进程
    public static void CloseAllExe()
    {
        Process[] ps = Process.GetProcesses();
        foreach (Process p in ps)
        {
            if (p.ProcessName.Equals("Client") // 主体程序的文件名,根据项目修改。
            {
                p.Kill();
            }
        }
    }
    
    // 直接启动主体程序
    ProcessStartInfo info = new ProcessStartInfo(System.Windows.Forms.Application.StartupPath + "\" + "Client.exe"); // D:workspaceMyProjectUpdateToolinDebugClient.exe
    Process.Start(info);
    Environment.Exit(0);

    重要参考: https://www.cnblogs.com/hiyz/archive/2012/07/12/2587458.html

  • 相关阅读:
    洛谷 P1005 矩阵取数游戏 (区间dp+高精度)
    洛谷 P1026 统计单词个数 (分组+子串预处理)(分组型dp再次总结)
    洛谷 P1052 过河 (离散化+dp)
    洛谷 P1541 乌龟棋 (四维费用背包)
    洛谷 P1736 创意吃鱼法
    矩阵旋转模板
    洛谷 P1855 榨取kkksc03 (二维费用背包)
    洛谷 P1417 烹调方案 (01背包拓展)
    关于结构体的PPT
    子进程自父进程继承什么或未继承什么
  • 原文地址:https://www.cnblogs.com/guxin/p/wpf-auto-update-tool.html
Copyright © 2020-2023  润新知