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

摘要:
想法:1。打开Visual Studio并在主程序的解决方案下创建一个名为自动更新程序的新项目。主程序的目录是D:workspaceMyProjectClient,而自动更新程序的目录则是D:worksspaceMyProjectUpdateTool。启动项目时,执行自动更新程序的Main()函数。首先检查自动更新程序本身是否需要更新!检查自我更新程序编译的Debug文件夹中的exe文件的版本号,如下所示。FileVersionInfofileVersionInfo=FileVersionInfo.GetVersionInfo;//ExecutablePath=D:workspaceMyProjectUpdateToolinDebugUpdateTool.exestringfileVersions=string.Format;3.自我更改程序的Main()函数确定是否需要通过传递参数来更新。自那时起,自动更新程序已更新到最新版本。

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

思路:

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

免责声明:文章转载自《【WPF】软件更新程序的设计思路》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Intellij IDEA 添加jar包的三种方式SecureCRT 工具 上传下载数据 与 ASCII、Xmodem、Ymodem 、Zmodem 说明下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Switch离线升级教程【自用】

想写这篇博客的原因还是因为自己发现明明已经自己通过大佬指导以及论坛教程指导,自己实践两次过了完整流程后,仍会因为相隔太久的固件更新而遗忘到底如何离线升级。当然这也是自己写的第一篇对于自己实用性较高的生活小技巧。 首先根据论坛大神的精华贴,为什么要对switch进行离线升级。首先升级很好理解,因为新游戏需要更新的系统支持下才能运行。因此在原生系统破解之后不足...

Microsoft Visual C++ Runtime Library Runtime Error的解决的方法

打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭。 一、 有些时候,在你安装、执行某个软件,可能会得到这样一个错误提示:   Microsoft Visual C++ Runtime Library  ...

tomcat域名重定向

例如:www.xxx.cn指向了服务器tomcat下的app1项目;        www.yyy.cn指向了服务器tomcat下的app2项目; 而域名管理中你只能将域名指向一个ip地址;所以你需要让浏览器访问不同域名的时候,让它指向tomcat下不同的项目; 我们默认将app1和app2放置tomcat下webapps目录下 需要配置config目录下...

Ubuntu16 编译源码安装MXNet 可变卷积Deformable-ConvNets GPU版

【引言】最近接手了公司的关于虫子识别的项目,使用MXNet框架开发,但是实际用的是Deformable-ConvNets. Deformable-ConvNets为微软研究研究院提出的可变卷积网络,可用于对图像中大小不一的物体识别,不是单单识别图中的猫和狗(它们都一般大小),而识别图像中不同种类的虫子(虫子本身小,而且难以区分),在这样的场景下很适合用可变...

OBS 录制视频 自己留存

1. 下载安装 软件下载地址:https://github.com/jp9000/obs-studio/releases/download/19.0.2/OBS-Studio-19.0.2-Full-Installer.exe安装就不用说了一路Next差不多就行了。 2. 设置 这里说的设置是指上传到youku上后可以用高清、超清、1080p进行播放。主要...

Android 性能优化:使用 Lint 优化代码、去除多余资源

http://blog.csdn.net/u011240877/article/details/54141714 *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 读完本文你将了解到: 前言 什么是 Lint Lint 工作方式简单介绍 从命令行运行 Lint Android Studio 中使用 Lint 团队中建立代码规范利器提...