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

思路:

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();

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

// 开始更新自更程序
App app = new App();
UpdateToolView view = new UpdateToolView(args[]);
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();

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

【WPF】软件更新程序的设计思路的更多相关文章

  1. WinForm关于更新程序的设计思路

    开发WINDOWS应用程序一般都会有一个自动更新的功能,这就需要提供一个单独的更新程序来更新主程序,那么主程序怎么检测是否有更新,以及更新程序怎么去更新主程序呢?下面将分开研究分析. 用VS发布向导发 ...

  2. WPF自动更新程序

    WPF AutoUpdater 描述: WPF+MVVM实现的自动更新程序 支持更新包文件验证(比较文件MD5码) 支持区分x86与x64程序的更新 支持更新程序的版本号 支持执行更新策略 截图: 使 ...

  3. 软件工程学习之小学四则混合运算出题软件 Version 1.1 设计思路及感想

    继上次采用形式文法来生成混合运算的算式,由于算法中没有引入控制参数而导致容易产生形式累赘(多余的括号等)的算式.本次更新决定采用一种更为简单有效的生成方式,由给出的一个随机的最终答案S,通过给定的一个 ...

  4. 软件工程学习之小学四则混合运算出题软件 Version 1.00 设计思路及感想

    对于小学四则混合运算出题软件的设计,通过分析设计要求,我觉得为了这个软件在今后便于功能上的扩充,可以利用上学期所学习的<编译原理>一课中的LL1语法分析及制导翻译的算法来实现.这样做的好处 ...

  5. Laravel 程序架构设计思路:使用动作类

    当我们谈论到应用程序的架构的时候,经常会问到一个经典的问题,那就是"这段代码应该放在哪里比较好". 因为 Laravel 是一个相当灵活的框架,所以要回答这个问题其实没那么容易.我 ...

  6. .Net自动更新程序GeneralUpdate,适用于wpf,winfrom,控制台应用

    什么是GeneralUpdate: GeneralUpdate是基于.net framwork4.5.2开发的一款(c/s应用)自动升级程序. 第一个版本叫Autoupdate(原博客: WPF自动更 ...

  7. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo

    26 集群使用初步 HDFS的设计思路 l 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: l 在大数据系统中作用: 为各类分布式 ...

  8. C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式

    C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式 C#实现自动启动的方法-两种方法 源码下载地址: ...

  9. ENode框架单台机器在处理Command时的设计思路

    设计目标 尽量快的处理命令和事件,保证吞吐量: 处理完一个命令后不需要等待命令产生的事件持久化完成就能处理下一个命令,从而保证领域内的业务逻辑处理不依赖于持久化IO,实现真正的in-memory: 保 ...

随机推荐

  1. MongoDB 学习笔记(1)

    数据库 一个mongodb中可以建立多个数据库. MongoDB的默认数据库为"db",该数据库存储在data目录中. MongoDB的单个实例可以容纳多个独立的数据库,每一个都有 ...

  2. Alan Cox:单向链表中prev指针的妙用

    之前发过一篇二级指针操作单向链表的例子,显示了C语言指针的灵活性,这次再探讨一个指针操作链表的例子,而且是一种完全不同的用法. 这个例子是linux-1.2.13网络协议栈里的,关于链表遍历& ...

  3. ASP.NET 的ClientIDMode属性

    在ASP.NET 4.0之前我们总是要为控件的ClientID头疼,比如明明一个叫lblName的Label放在一个叫做grd的GridView里面后,在页面上改Label的ID就变成了诸如grd_c ...

  4. 【转载并整理】Linux - centOS 6 SVN服务器安装、配置及开机启动

    以前在windows上安装svn服务器,用的是VisualSVN-Server用起来还不错,但只能用在windows,在linux上部署使用是 subversion,具体说明如下 参考原文:http: ...

  5. windows系统如何通过Xshell 客户端连接 linux系统(主要介绍ubuntu系统)

    一. 1.查看ubuntu系统的ip地址:ifconfig 在window系统运行窗口下:ping ubuntu系统的IP地址:例如:ping 192.168.163.129 出现下述命令就是ping ...

  6. Vue 的开始

    1 框架的 MVVM 模式 ViewModel是Vue.js的核心,它是一个Vue实例.Vue实例是作用于某一个HTML元素上的,这个元素可以是HTML的body元素,也可以是指定了id的某个元素. ...

  7. Ubuntu 14.04 静态IP设置, ping通win7

    ubuntu 14.04以后不支持 /etc/init.d/networing restart命令,使用ifdown et0 和ifup eth0 使用echo $?查看上一次命令执行的结果 ifdo ...

  8. vs 2017打包安装包(印象深刻)

    Visual Studio Install 打包安装项目2017 以下是具体步骤 一.安装环境 1.下载:链接地址 2.安装vs2017的时候需要安装依赖 .NET framework 4.6 .下载 ...

  9. nmap 端口扫描工具

    nmap工具介绍 一.简介 nmap :也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包. nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端.确定哪些服务 ...

  10. [svc]mount命令及解决因/etc/fstab错误导致系统不能启动故障

    mount命令-手动挂载设备 格式: mount [options] [-t fstype] [-o option] 设备 挂载点 mount -n -o remount,rw / - Mount t ...