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#将list类型转换成DataTable方法示例

    针对这个问题,我为您提供以下完整攻略: 问题描述 在使用C#进行开发的过程中,由于不同数据结构之间的差异,我们需要将一些数据类型进行转换。其中,将List类型数据转换成DataTable是经常需要的操作。那么,如何将List类型转换成DataTable呢?下面就是详细的攻略。 解决方案 下面我们就来看看如何使用C#将List类型转换成DataTable。 方…

    C# 2023年5月31日
    00
  • C#多线程系列之任务基础(二)

    下面是关于”C#多线程系列之任务基础(二)”的详细讲解。 标题 C#多线程系列之任务基础(二) 代码块 var task = Task.Run(() => { // 这里是异步执行的任务代码 }); 正文 本文主要讲解了在C#中利用Task实现多线程编程的基础知识。在任务基础(一)中,我们讲解了Task的基本概念、使用方法以及几种等待任务完成的方法。在…

    C# 2023年6月3日
    00
  • asp.net下中文验证码,免费开源代码

    当需要在ASP.NET网站中添加中文验证码时,可以使用免费的开源代码库来实现。以下是完整的攻略。 步骤一:下载中文验证码代码库 可以从GitHub上下载中文验证码的开源代码库。该代码库提供了在ASP.NET和MVC网站中添加中文验证码的功能。下载地址:https://github.com/rui2dou/captcha-aspnet。 步骤二:将代码库添加到…

    C# 2023年5月31日
    00
  • C#中efcore-ShardingCore呈现“完美”分表

    我会详细讲解“C#中efcore-ShardingCore呈现‘完美’分表”的完整攻略,并包含两条示例说明。 ShardingCore 什么是ShardingCore? ShardingCore是一个基于EF Core的分表库,它提供了完美的分表功能,欢迎大家去GitHub上了解更多信息。 ShardingCore分表的实现方式 ShardingCore实现…

    C# 2023年5月31日
    00
  • ASP 使用三层架构 asp中使用类

    ASP(Active Server Pages)是一种动态网页开发技术,而三层架构则是一种常用的软件架构,采用三层架构能够有效地将程序分层,分离不同的功能模块,使得程序更加易于维护和扩展。 使用三层架构可以将程序分为三个层次:表示层、业务逻辑层和数据访问层。 表示层 表示层主要负责与用户进行交互,呈现数据,通过HTML/CSS/JS等技术将网页呈现给用户。 …

    C# 2023年6月8日
    00
  • c#中LINQ的基本用法(三)

    c#中LINQ的基本用法(三) 在C#中,LINQ(Language Integrated Query)是一种强大的查询语言,可以用于查询各种数据源,如数组、集合、数据库等。本文将介绍LINQ的基本用法,包括分组、聚合、排序和连接等。 分组 分组是指将数据按照某个属性进行分组,以便更好地统计和分析数据。在LINQ中,可以使用group关键字进行分组操作。 以…

    C# 2023年5月15日
    00
  • Unity 如何批量修改FBX模型

    当需要批量修改FBX模型时,可以使用Unity的批量处理功能。以下是完整的攻略: 步骤一:导入FBX模型 首先,将需要批量修改的FBX模型导入到Unity中。可以通过拖拽文件到Project视图或者点击菜单栏上的“Assets”→“Import New Asset”来完成导入。 步骤二:创建脚本 创建新的脚本,用于修改我们导入的模型。可以在Unity编辑器中…

    C# 2023年6月3日
    00
  • C#实现组合排列的方法

    我们知道,组合和排列是组合数学中的两个基本概念。这两个概念经常会在编程中用到,因此在C#中实现它们是非常必要的。 什么是组合? 组合是从n个元素中取出m个元素(m<=n),不考虑元素的顺序,这样的m元组的个数叫做从n个不同元素中取出m个元素的组合数。 组合数的计算公式为C(n,m) = n!/(m! * (n-m)!)。 什么是排列? 排列是从n个元素…

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