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

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

思路:

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

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:\workspace\MyProject\UpdateTool\bin\Debug\UpdateTool.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:\workspace\MyProject\UpdateTool\bin\Debug\UpdateTool.exe
string target = cachePath + "\\" + name + ".exe"; // C:\\Users\Administrator\AppData\Roaming\mjl\UpdateTool.exe
File.Copy(source, target, true);
string arg = System.Windows.Forms.Application.StartupPath; // D:\workspace\MyProject\UpdateTool\bin\Debug
if (!string.IsNullOrEmpty(updateUrl))
{
    arg += ("|" + updateUrl); // D:\workspace\MyProject\UpdateTool\bin\Debug|/assets/file/1518053629860.zip
}
arg = "\"" + arg + "\""; // "D:\workspace\MyProject\UpdateTool\bin\Debug|/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:\workspace\MyProject\UpdateTool\bin\Debug\Client.exe
Process.Start(info);
Environment.Exit(0);

 


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

posted @ 2018-03-06 16:53  霍莉雪特  阅读(3562)  评论(0编辑  收藏  举报