C# WinForm实现自动更新程序之客户端的示例代码
作者:Csharp小记 发布时间:2022-03-28 03:26:24
标签:C#,WinForm,更新,程序
前言
第二步理论上我们该写客户端了,但是,在此之前,需要先介绍下一些必要的方法以及操作。
写代码还是要尽量的保证通用性,以便以后需要的时候可以拿来稍微改改甚至直接使用。所以在这里我们将自动更新的程序抽象出来,即对于客户端来说,它只包含三个文件(AutoUpdate.dll、AutoUpdate.exe、UpdateList.xml,如果是.NET Framework的话,其实是没有AutoUpdate.dll文件的,就一个exe就足够了。这也是我为什么一直不用NET Core来写Winform程序的原因之一);然后将这三个文件放到主程序的目录中即可。
然后就是传参调用,在Program文件中做了以下代码操作。所以调用的时候需要将主程序的执行目录以及进程名传过来,作用分别是再更新完后自动启动以及更新之前把相关的进程杀掉以便完成更新。
同时可以看到在更新的时候,有一个图片旋转的动作,也一并放到此篇文章中。
开发环境
.NET Core 3.1
开发工具
Visual Studio 2019
实现代码
//更新程序
namespace AutoUpdate {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args) {
if(args.Length != 1) {
return;
}
var arg = args[0].Split("|*|");
if(arg.Length == 0) {
return;
}
string runPath = arg[0];
string procesName = arg[1];
Process[] processes = Process.GetProcesses();
foreach(Process process in processes) {
if(process.ProcessName == procesName) {
process.Kill(true);
}
}
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form_update(runPath));
}
}
}
//主程序
namespace AutoUpdate.Test {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Update();
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
readonly static string updateXml = Application.StartupPath + "UpdateList.xml";
/// <summary>
/// 获取本地更新地址
/// </summary>
/// <returns></returns>
static string GetUpdateUrl() {
XElement xele = XElement.Load(updateXml);
string url = xele.Element("url").Value;
return url;
}
/// <summary>
/// 获取本地更新文件
/// </summary>
/// <returns></returns>
static string GetUpdateFiles() {
XDocument xdoc = XDocument.Load(updateXml);
var files = from f in xdoc.Root.Element("files").Elements() select new { name = f.Attribute("name").Value, version = f.Attribute("version").Value };
return JsonConvert.SerializeObject(files);
}
/// <summary>
/// 检查是否需要更新
/// </summary>
/// <returns></returns>
static bool CheckUpdate() {
string url = GetUpdateUrl();
HttpResult httpResult = HttpUtil.HttpRequest(new HttpItem(url + "GetUpdateFiles", requestData: GetUpdateFiles()));
if(httpResult.Status) {
UpdateModel_Out output = JsonConvert.DeserializeObject<UpdateModel_Out>(httpResult.HttpStringData);
if(output.updateList.Count > 0)
return true;
}
return false;
}
static void Update() {
if(CheckUpdate()) {
string processName = Assembly.GetExecutingAssembly().GetName().Name;
ProcessStartInfo info = new ProcessStartInfo(Application.StartupPath + "AutoUpdate.exe", Process.GetCurrentProcess().MainModule.FileName + "|*|" + processName);
Process.Start(info);
Environment.Exit(0);
}
}
}
}
public static class ImageEx {
/// <summary>
/// 旋转图片
/// </summary>
/// <param name="image"></param>
/// <param name="angle"></param>
/// <returns></returns>
public static Image RotateImage(this Image image, float angle) {
if(image == null)
throw new ArgumentNullException("image");
float dx = image.Width / 2.0f;
float dy = image.Height / 2.0f;
Bitmap rotatedBmp = new Bitmap(image.Width, image.Height);
rotatedBmp.SetResolution(image.HorizontalResolution, image.VerticalResolution);
Graphics g = Graphics.FromImage(rotatedBmp);
g.TranslateTransform(dx, dy);
g.RotateTransform(angle);
g.TranslateTransform(-dx, -dy);
g.DrawImage(image, new PointF(0, 0));
g.Dispose();
return rotatedBmp;
}
}
实现效果
代码解析
这里可以关注下在主程序中的获取更新地址以及文件等方法,其实我这里是有重复判断的,即在主程序中判断了一遍,还会在更新程序中判断一遍,如果觉得不需要,可以执行选择去掉,全部交给更新程序去做。但是也就需要统一放在更新程序的入口中做处理了,相对而言,我觉得写两遍还是很方便。
来源:https://mp.weixin.qq.com/s/exBuBXzQLQNZyK2FLxGl_A


猜你喜欢
- 最终效果如下大概就几个步骤1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4.项目准备 5.编写 Dock
- 目录1.摘要2.C#中定时任务的最简方法3.定时任务阻塞现象4.阻塞现象原因分析5.问题解决总结1.摘要本文会介绍一个C#中最简单定时任务的
- 工具类之前用AsyncTask 现在改用rxJavapublic class SaveImageUtils { pu
- 最近开发遇到了个问题,app升级的时候,其他手机都能正常升级,下载完安装包,跳到安装页面进行新版本的安装。但却有用户反映,华为P10和华为M
- 1.小程序推送信息列如我们去餐厅等位有预约提醒,剩余桌数首先申请一个小程序,微信开放平台:小程序2.申请小程序信息,申请信息模板appid&
- 本文实例为大家分享了C# Winform选项卡集成窗体的具体代码,供大家参考,具体内容如下知识要点:利用反射动态的加载窗体到对应的TabPa
- 1、SSL介绍和说明SSL的配置也是我们在实际应用中经常遇到的场景SSL(Secure Sockets Layer,安全套接层)是为网络通信
- 上篇文章给大家介绍了springboot对接第三方微信授权及获取用户的头像和昵称等等1 账户注销1.1 在SecurityConfig中加入
- Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "hello";,另一种就是使用new
- 一、示例搭建步骤先给出本文示例代码:WpfWithCefSharpDemo。1. 创建项目创建一个WPF项目,比如命名为&ldquo
- 某些情况下,我们需要在项目中对多种任务分配不同的线程池进行执行。从而通过监控不同的线程池来控制不同的任务。为了达到这个目的,需要在项目中配置
- 在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 用个比较通俗的比如,任何一个守
- eureka获取服务ip和端口号进行Http调用我告诉你们为啥我要先从eureka首先获取 goods的服务ip, 在用ip的方式使用htt
- 对接支付宝支付接口,官方文档已经写的很清楚了,但是也有很多像我一样的小白,第一次对接支付宝支付接口,会有些迷茫,所以我在此写下这篇文章,给我
- 在日常开发中我们经常会使用到行情数据,很多的时候我们根据一个基准数据区构造行情,但是随着时间的推移然来构造的数据与真实行情数据之间的差距越来
- 这个东西我已经用了有段时间了,从开始写文章就在用这个,主要原因还是因为我比较懒。懒得去寻找图片,同时又怕万一惹来版权争议。。。跟我所有的文章
- C#的System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能。包括了.NET下的非泛型集合类以及非
- 实例如下所示:public class JsonExtracter { public static void main(String[] a
- layout<?xml version="1.0"?>-<LinearLayout android:p
- 目录 一、Implicit和Explicit1、Implicit2、、Explicit先上一段奇怪的代码:if (dto.Paym