C# WinForm实现自动更新程序之客户端的示例代码

作者:Csharp小记 时间:2022-03-28 03:26:24 

前言

第二步理论上我们该写客户端了,但是,在此之前,需要先介绍下一些必要的方法以及操作。

写代码还是要尽量的保证通用性,以便以后需要的时候可以拿来稍微改改甚至直接使用。所以在这里我们将自动更新的程序抽象出来,即对于客户端来说,它只包含三个文件(AutoUpdate.dll、AutoUpdate.exe、UpdateList.xml,如果是.NET Framework的话,其实是没有AutoUpdate.dll文件的,就一个exe就足够了。这也是我为什么一直不用NET Core来写Winform程序的原因之一);然后将这三个文件放到主程序的目录中即可。

然后就是传参调用,在Program文件中做了以下代码操作。所以调用的时候需要将主程序的执行目录以及进程名传过来,作用分别是再更新完后自动启动以及更新之前把相关的进程杀掉以便完成更新。

同时可以看到在更新的时候,有一个图片旋转的动作,也一并放到此篇文章中。

C# WinForm实现自动更新程序之客户端的示例代码

开发环境

.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;
       }
   }

实现效果

C# WinForm实现自动更新程序之客户端的示例代码

代码解析

这里可以关注下在主程序中的获取更新地址以及文件等方法,其实我这里是有重复判断的,即在主程序中判断了一遍,还会在更新程序中判断一遍,如果觉得不需要,可以执行选择去掉,全部交给更新程序去做。但是也就需要统一放在更新程序的入口中做处理了,相对而言,我觉得写两遍还是很方便。

来源:https://mp.weixin.qq.com/s/exBuBXzQLQNZyK2FLxGl_A

标签:C#,WinForm,更新,程序
0
投稿

猜你喜欢

  • Java高级特性之反射机制实例详解

    2023-10-08 06:33:51
  • Java中Future和FutureTask的示例详解及使用

    2023-01-29 11:48:42
  • 一起来学习C#的观察者模式

    2022-04-02 13:43:15
  • C#控件Picturebox实现鼠标拖拽功能

    2021-10-30 20:52:36
  • IDEA实现添加 前进后退 到工具栏的操作

    2021-08-30 21:34:48
  • 基于java的opencv开发过程详解

    2022-03-31 20:02:59
  • Java 8 中的 10 个特性总结及详解

    2023-07-21 00:06:51
  • 全面理解java中的异常处理机制

    2023-10-26 04:08:20
  • C# 9.0 特性全面总结

    2023-07-21 16:28:19
  • Idea中SpringBoot多模块项目的建立实现

    2023-11-08 07:52:34
  • Android编程之ListView和EditText发布帖子隐藏软键盘功能详解

    2023-11-06 23:09:55
  • Java 中的垃圾回收机制详解

    2023-01-11 19:32:34
  • android异步消息机制 源码层面彻底解析(1)

    2023-10-02 07:08:52
  • 浅谈java异常链与异常丢失

    2023-10-24 21:53:38
  • C#中调用SAPI实现语音合成的2种方法

    2023-07-07 09:36:00
  • 老生常谈 Java中的继承(必看)

    2023-06-21 11:59:51
  • 详解如何在SpringBoot项目中使用统一返回结果

    2023-10-30 16:41:21
  • MyBatis的嵌套查询解析

    2023-11-26 16:58:46
  • Java枚举类与注解,新手一篇搞定它

    2022-03-10 08:47:52
  • Java 8 中 Function 接口使用方法介绍

    2022-12-08 23:54:39
  • asp之家 软件编程 m.aspxhome.com