c# 如何实现自动更新程序

针对C#如何实现自动更新程序,一般有两种实现方式,分别是:

1.使用ClickOnce部署

ClickOnce是微软公司提供的一种快速、简单的部署技术,可以帮助开发人员轻松地完成应用程序的自动更新。其主要优点是使用简便、稳定性高、和Windows操作系统深度耦合。

其中实现步骤如下:

  • 首先,我们需要在Visual Studio中针对该应用程序进行发布设置,定义更新选项。
  • 点击“项目” → “发布” → 选择“发布向导”。
  • 下一步,选择“从我的计算机启动” → 点击“浏览”,选择保存位置
  • 设置“启动时检查更新”为“启动应用程序时” → 完成

完成之后,运行应用程序会在本地生成一个安装文件和一个应用程序清单,当用户运行此程序时,ClickOnce会自动检查更新,并提示用户更新。

2.使用自行编写更新器程序

另一种自动更新的方式是,我们自己编写一个软件更新程序,这种方法通常会在原程序首次安装时,安装一个检查更新的模块,或在原程序中加入检查更新的代码模块。当软件更新程序检测到当前版本不是最新版本时,自动下载并运行最新版本的安装程序。

具体实现步骤如下:

  • 在程序中实现检测更新的模块,并且定义更新的服务器地址。
  • 程序启动时,进行自动检查当前版本,如果更新,则下载最新的程序版本,并以静默方式安装。
  • 在应用程序内部实现原版本的卸载和最新版本的安装等操作,以达到自更新的目的。

这种方式可以使用各种语言来实现,例如使用C#编写更新程序,关键在于处理版本更新的逻辑。

下面是两种方式的示例程序:

  1. ClickOnce自动更新示例

这是Vistual Studio自带的点击一键发布实现自动更新的程序。需要创建一个应用程序,并发布运行后,会自动检测更新并更新。

https://docs.microsoft.com/zh-cn/visualstudio/deployment/how-to-publish-a-clickonce-application?view=vs-2019

  1. 自定义自动更新程序示例

下面是一个基于C#的自动更新程序的代码示例,主要实现了检测软件版本、更新程序下载、卸载旧版本、安装新版本等功能。

using System;
using System.ComponentModel;
using System.Net;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Diagnostics;

namespace AutoUpdater
{
    public class UpdateManager
    {
        private readonly string _appName;
        private readonly string _appDir;
        private readonly string _updateUrl;

        private readonly BackgroundWorker _worker;

        public UpdateManager(string appName, string appDir, string updateUrl)
        {
            _appName = appName;
            _appDir = appDir;
            _updateUrl = updateUrl;

            _worker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true,
            };
            _worker.DoWork += OnDoWork;
            _worker.ProgressChanged += OnProgressChanged;
            _worker.RunWorkerCompleted += OnCompleted;
        }

        public void StartUpdateIfNeeded()
        {
            if (!_worker.IsBusy)
            {
                _worker.RunWorkerAsync();
            }
        }

        private void OnDoWork(object sender, DoWorkEventArgs e)
        {
            var progress = 0;
            var state = "";
            var version = GetLastestVersion(ref progress, ref state);
            if (version == null) return;

            if (version > Assembly.GetExecutingAssembly().GetName().Version)
            {
                DownloadAndInstallVersion(version, ref progress, ref state);
            }
        }

        private Version GetLastestVersion(ref int progress, ref string state)
        {
            progress = 10;
            state = "正在检查更新...";
            var req = WebRequest.Create(_updateUrl);
            req.Timeout = 15000;
            var resp = req.GetResponse();
            var mtime = resp.Headers["Last-Modified"];
            Version version = null;

            if (mtime != null && DateTime.TryParse(mtime, out var lastModified))
            {
                progress = 20;

                version = new Version(resp.Headers["Update-Version"]);
                if (version > Assembly.GetExecutingAssembly().GetName().Version)
                {
                    state = $"发现新的版本 {version}";
                    progress = 50;
                }
                else
                {
                    state = "当前是最新版本,不需要更新。";
                    progress = 100;
                }
            }

            return version;
        }

        private void DownloadAndInstallVersion(Version version, ref int progress, ref string state)
        {
            state = $"开始下载新的版本 {version}...";
            progress = 60;

            using (var client = new WebClient())
            {
                client.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.Now.ToString();
                client.DownloadProgressChanged += (s, e) => {
                    progress = 60 + e.ProgressPercentage * 4 / 5;
                    state = $"正在下载 {e.ProgressPercentage}%...";
                };
                var file = Path.Combine(_appDir, $"setup-{version}.exe");
                client.DownloadFile(new Uri($"{_updateUrl}/{version}"), file);

                state = $"下载完成,准备卸载旧版本并安装新版本...";
                progress = 90;
                var uninstaller = Path.Combine(_appDir, "uninstall.exe");
                if (File.Exists(uninstaller))
                {
                    Process.Start(uninstaller).WaitForExit();
                }

                Process.Start(file, "/VERYSILENT /SUPRESSMSGBOXES").WaitForExit();
            }

            state = "安装完成,请关闭程序重新打开。";
            progress = 100;
        }

        private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine($"[{DateTime.Now}] {e.ProgressPercentage}%: {e.UserState}");
        }

        private void OnCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // do something
        }
    }
}

该示例程序包含了自定义的UpdateManager类,用于检测程序是否存在更新。可以在所有涉及到更新检测的地方调用该类的StartUpdateIfNeeded()方法即可实现自动更新。其中需要手动在服务端实现版本号解析与传输等功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c# 如何实现自动更新程序 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • C#中字符串编码处理

    C#中字符串的编码处理需要涉及到多个类和方法。下面将从以下三个方面进行详细说明: 字符集 C#中使用Unicode字符集表示字符串,同时也支持使用ASCII和UTF-8字符集。Unicode字符集定义了每个字符与二进制编码之间的映射关系。ASCII字符集是Unicode字符集的子集,只包含128个常用字符。UTF-8字符集是一种变长编码,可以用1-4个字节表…

    C# 2023年6月7日
    00
  • C# Lambda表达式及Lambda表达式树的创建过程

    让我们来详细讲解一下C# Lambda表达式及Lambda表达式树的创建过程。 什么是Lambda表达式 Lambda表达式是C# 3.0引入的一种新的语言特性,它是一种可创建委托或表达式树类型的匿名函数。可以将Lambda表达式看作一个简短的函数,它没有名称,但它可以被赋值给委托类型或表达式树类型。 Lambda表达式的基本语法格式如下: (paramet…

    C# 2023年5月31日
    00
  • WPF如何利用附加属性修改ShowGridLines效果详解

    下面是详细的攻略: 什么是WPF附加属性? WPF附加属性是一种特殊的属性,在WPF控件中可用。它允许你指定控件的属性,作用于其它控件,与父控件或者与容器进行交互。在XAML代码中,附加属性使用特殊的语法来定义:使用父控件名称作为前缀,并用一个“.”隔开,后面跟着属性名称。例如,Grid.Row=”1″中的“Row”是一个附加属性,作用于Grid实例,而非R…

    C# 2023年6月6日
    00
  • C#实现Winform版计算器

    这里是C#实现Winform版计算器的完整攻略: 1. 确定项目的需求和功能 在开始任何项目之前,首先要确定项目的需求和功能,这样可以帮助我们更好地规划和实施项目。对于一个计算器,我们至少需要实现以下功能: 基本运算:加减乘除 清除:清空当前输入和结果 回退:撤销上一步输入 小数点:支持小数计算 防止错误输入:例如除以0等情况 确定以上需求和功能后,我们可以…

    C# 2023年6月6日
    00
  • Blazor UI库 Bootstrap Blazor 快速上手 (v7.5.7)

    最近组件库更新比较频繁,有些同学感觉有点迷茫,就着今天刚上了张老板一节课立马撸个新的上手教程回馈社区, ;-> 1.新建工程b18QuickStartv757,将项目添加到解决方案中 dotnet new blazorserver -o b18QuickStartv757 dotnet sln add b18QuickStartv757/b18Quic…

    C# 2023年5月4日
    00
  • C# File.GetLastWriteTime(string path):获取指定文件的最后修改时间

    C# File.GetLastWriteTime(string path)方法 简介 File.GetLastWriteTime(string path)方法返回指定文件或目录的最后修改日期和时间。 使用方法 语法 public static DateTime GetLastWriteTime (string path); 参数 参数 描述 path 文件或…

    C# 2023年4月19日
    00
  • C#中的 == 和equals()区别浅析

    C#中的==和equals()区别浅析 在C#中,我们经常会使用 == 运算符和 equals() 方法来比较两个对象是否相等。但是,你是否知道它们的区别呢?本文将深入探讨 == 和 equals() 方法之间的区别,并提供一些示例来帮助你更好的理解它们之间的差异。 == 运算符 首先来看 == 运算符。C#中的 == 运算符用于比较两个对象的值是否相等。如…

    C# 2023年5月15日
    00
  • ASP.NET CORE读取json格式配置文件

    ASP.NET Core 读取 JSON 格式配置文件的流程: 在 appsettings.json 文件中定义所需的配置项。 在 Program.cs 文件中使用 CreateDefaultBuilder(args) 方法创建 IHostBuilder 对象,并在 ConfigureAppConfiguration(…) 方法中添加读取配置文件的功能。…

    C# 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部