c#自动更新升级工具

c#更新工具,wpf开发,所有windows桌面程序均可使用,基于.net 4.0,最低支持windos xp系统

更新工具优点

  • 使用简单
  • 批量更新
  • 跨版本更新
  • 数据备份
  • 手动还原数据
  • 体积小

程序更新使用效果

在这里插入图片描述

使用简单

只需添加两个类,以及三个路径的指定,就可以从任何地方下载更新包,并解压到主程序目录中,自动启动
在这里插入图片描述
在这里插入图片描述

批量更新

不管你从后台拿到了多少个升级包,都能一次性完成升级(以下升级包为本地测试数据)
在这里插入图片描述

手动还原数据至上一版本

在这里插入图片描述

体积小

依赖少,占用空间少
在这里插入图片描述

如何使用

添加类ClientParameter.cs

    public class ClientParameter
    {
        /// <summary>
        /// 1:MainApp 2:UpdateApp
        /// </summary>
        public int AppType { get; set; } = 1;

        /// <summary>
        /// 启动程序名称(可以加上相对路径)
        /// </summary>
        public string AppName { get; set; }

        /// <summary>
        /// 下载的内容放到哪里
        /// </summary>
        public string DownLoadPath { get; set; }

        /// <summary>
        /// 解压的内容放到哪里
        /// </summary>
        public string UnZipPath { get; set; }
        /// <summary>
        /// 备份地址
        /// </summary>
        public string BackUpPath { get; set; }
        /// <summary>
        /// 客户端版本当前
        /// </summary>
        public string ClientVersion { get; set; }
        /// <summary>
        /// 日志访问地址
        /// </summary>
        public string UpdateLogUrl { get; set; }
        /// <summary>
        /// 是否修改目标版本(通过修改version.ini的方式统一控制版本)
        /// </summary>
        public bool IsUpdateVersion { get; set; } = true;
        /// <summary>
        /// 是否是还原版本
        /// </summary>
        public bool IsRestore { get; set; } = false;
        /// <summary>
        /// 多版本更新
        /// </summary>
        public List<UpdateVersion> UpdateVersions { get; set; }
    }
    public class UpdateVersion
    {
        public UpdateVersion(string version, string url, string name, bool isUpdate = true)
        {
            Version = version;
            Url = url;
            Name = name;
            IsUpdate = isUpdate;
        }
        public UpdateVersion(string version, string url, bool isUpdate = true)
        {
            Version = version;
            Url = url;
            IsUpdate = isUpdate;
        }
        /// <summary>
        /// 更新的包名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 更新的版本
        /// </summary>
        public string Version { get; set; }

        /// <summary>
        /// 包地址
        /// </summary>
        public string Url { get; set; }
        /// <summary>
        /// 是否更新
        /// </summary>
        public bool IsUpdate { get; set; }
    }

添加类UpdateUtil.cs

    public static class UpdateUtil
    {
        #region API函数声明-必须放在类中
        [DllImport("kernel32")]//返回0表示失败,非0为成功
        private static extern long WritePrivateProfileString(string section, string key,
          string val, string filePath);
        [DllImport("kernel32")]//返回取得字符串缓冲区的长度
        private static extern long GetPrivateProfileString(string section, string key,
          string def, StringBuilder retVal, int size, string filePath);
        #endregion

        public static string Serialize(object obj)
        {
            if (obj == null) return string.Empty;
            var json = JsonConvert.SerializeObject(obj);
            var bytes = Encoding.Default.GetBytes(json);
            var base64str = Convert.ToBase64String(bytes);
            return base64str;
        }

        public static T Deserialize<T>(string str)
        {
            var obj = default(T);
            if (string.IsNullOrEmpty(str)) return obj;
            try
            {
                byte[] bytes = Convert.FromBase64String(str);
                var json = Encoding.Default.GetString(bytes);
                var result = JsonConvert.DeserializeObject<T>(json);
                return result;

            }
            catch (Exception)
            {
                return default;
            }

        }
        #region 写Ini文件
        /// <summary>
        /// 将内容写入指定的ini文件中
        /// </summary>
        /// <param name="Section">ini文件中的节名</param>
        /// <param name="Key">ini文件中的键</param>
        /// <param name="Value">要写入该键所对应的值</param>
        /// <param name="iniFilePath">ini文件路径</param>
        /// <returns></returns>
        public static bool Write(string Section, string Key, string Value, string iniFilePath)
        {

            if (!File.Exists(iniFilePath))
            {
                try
                {
                    FileStream stream = File.Open(iniFilePath, FileMode.Create, FileAccess.Write);
                    //stream.Seek(0, SeekOrigin.Begin);
                    //stream.SetLength(0); //清空txt文件
                    stream.Dispose();
                    stream.Close();
                }
                catch (Exception ex)
                {

                    Console.WriteLine(ex);
                }

            }

            if (File.Exists(iniFilePath))
            {
                long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
                if (OpStation == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }

        }
        #endregion
        /// <summary>
        /// 读取ini文件内容的方法
        /// </summary>
        /// <param name="Section">ini文件的节名</param>
        /// <param name="Key">ini文件对应节下的健名</param>
        /// <param name="NoText">ini文件对应节对应健下无内容时返回的值</param>
        /// <param name="iniFilePath">该ini文件的路径</param>
        /// <returns></returns>
        public static string Read(string Section, string Key, string NoText, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                StringBuilder temp = new StringBuilder(1024);
                GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
                return temp.ToString();
            }
            else
            {
                return null;
            }
        }
    }

生成的程序项目结构如下
在这里插入图片描述
主程序生成至current文件夹下,更新程序生成至update文件夹下
在这里插入图片描述
在这里插入图片描述
执行更新处添加如下代码

 ClientParameter clientParameter = new ClientParameter {
                AppName = appName,
                BackUpPath = backUpPath,
                DownLoadPath = downLoadPath,//下载包临时存放位置 可默认
                UnZipPath = unZipPath,//解压文件存放位置,可默认
                UpdateLogUrl = "",//更新成功后会自动跳转至该路径 为空则不跳转
                UpdateVersions = new List<UpdateVersion> {
                            new UpdateVersion("1.0.2","http://127.0.0.1:5000/v3.23.12_202312051713.zip"),
                            new UpdateVersion("1.0.3","http://127.0.0.1:5000/Avalonia-11.0.0-preview4.zip"),
                            //new UpdateVersion("1.0.4","http://127.0.0.1:5000/Dragablz-master.zip"),
                            new UpdateVersion("1.0.5","http://127.0.0.1:5000/EChartsSDK-master.zip"),
                            new UpdateVersion("1.0.6","http://127.0.0.1:5000/EChartsNet-master.zip"),
                            //new UpdateVersion("1.0.7","http://127.0.0.1:5000/HandyControl-master.zip"),
                            new UpdateVersion("1.0.8","http://127.0.0.1:5000/Live-Charts-master.zip"),
                        }
            };


            string arg = UpdateUtil.Serialize(clientParameter);

            var path = directInfo.Parent.FullName + @"\download\Cloud.Update.exe";
            if (File.Exists(path))
            {
                Process.Start(path, arg);
                Process.GetCurrentProcess().Kill();
            }

关于测试下载环境的搭建

新建 asp.net core webapi 项目

在这里插入图片描述
如同取消勾选
在这里插入图片描述
program.cs添加静态文件支持

         app.UseStaticFiles();

在这里插入图片描述
重新生成代码
在这里插入图片描述
到debug目录下新建wwwroot文件夹
在这里插入图片描述
将用来测试的压缩包放到wwwroot文件夹下,注意以.zip的格式结尾
在这里插入图片描述
回到程序目录双击启动
在这里插入图片描述
在这里插入图片描述
在浏览器输入http://localhost:5000/v3.23.12_202312051713.zip,回车测试下载服务是否正常
在这里插入图片描述
可以看到成功下载了压缩包,至此下载环境搭建完成
在这里插入图片描述
代码地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/307083.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

哥伦比亚电影平台,影业之路的的新起点

哥伦比亚影业&#xff08;英语&#xff1a;Columbia Pictures&#xff09;作为与米高梅公司同为美国历史悠久的电影公司&#xff0c;其发展历程可以说是世界电影行业的缩影&#xff0c;从创立时的CBC电影行销公司&#xff08;英语&#xff1a;CBC Film Sales Corporation&#…

构建自己的私人GPT-支持中文

上一篇已经讲解了如何构建自己的私人GPT&#xff0c;这一篇主要讲如何让GPT支持中文。 privateGPT 本地部署目前只支持基于llama.cpp 的 gguf格式模型&#xff0c;GGUF 是 llama.cpp 团队于 2023 年 8 月 21 日推出的一种新格式。它是 GGML 的替代品&#xff0c;llama.cpp 不再…

Fedora Linux 中安装 nginx

Fedora 35 中安装 nginx 的方法非常简单。 运行下面的命令&#xff1a; sudo dnf install nginx 在提示你需要确认的地方&#xff0c;输入 y 后回车即可。 开机自动启动 如果你希望在你的操作系统重启的时候自动启动 nginx&#xff0c;请输入下面的命令&#xff1a; syst…

VsCode 配置Copilot的详细步骤与示例

目录 一、 GitHub Copilot Chat 账号申请 1.1 前往 GitHub 网站&#xff08;https://github.com/&#xff09;并点击 "Sign up" 进行注册。 1.2 申请 GitHub Copilot Chat 二、VsCode 配置 Copilot 2.1 安装 VsCode 编辑器 2.2 安装 Copilot 插件 2.3 配置Git…

C++|19.C++类与结构体对比

类和结构体 类和结构体本质上并没有太大区别。 但两者在默认上有所区别。 类默认成员变量是私有的&#xff0c;而结构体默认成员变量是公有的。 也就是说&#xff0c;对于一个类来说&#xff0c;会默认使用private去保护其内部成员变量使得无法直接访问到其内部的变量。 同时从…

简谈以太网的工作原理及传输介质

以太网是一种常见的局域网技术&#xff0c;它采用 CSMA/CD&#xff08;载波侦听多路接入/冲突检测&#xff09;的介质访问控制方式&#xff0c;用于在局域网中传输数据。本文将介绍以太网的工作原理以及常见的传输介质。 一、以太网的工作原理以太网的工作原理基于CSMA/CD机制…

C#PDF转Excel

組件 Spire.Pdf.dll, v7.8.9.0 【注意&#xff1a;版本太低的没有此功能】 在Visual Studio中找到参考&#xff0c;鼠标右键点击“引用”&#xff0c;“添加引用”&#xff0c;将本地路径debug文件夹下的dll文件添加引用至程序。 界面图&#xff1a; 1个label&#xff0c;1…

融云 CEO 董晗荣获 51CTO 「2023 年度科技影响力人物奖」

&#xff08;&#x1f446;点击获取《社交泛娱乐出海作战地图》&#xff09; 1 月 5 日&#xff0c;由知名 IT 技术媒体 51CTO 主办的第十八届“中国企业年终评选”正式揭晓榜单&#xff0c;融云 CEO 董晗荣获“2023 年度科技影响力人物奖”。关注【融云全球互联网通信云】了解…

_Incapsula_Resource与Rc4混淆分析

一、获得混淆js 这么一个地址 https://www.interasia.cc/_Incapsula_Resource?SWJIYLWA5074a744e2e3d891814e9a2dace20bd4,719d34d31c8e3a6e6fffd425f7e032f3 浏览器打开这个地址 复制这个js&#xff0c;到浏览器调试 先格式化查看&#xff0c;也就是一个eval函数执行b函数 …

SemiDrive E3 打包说明

一、 概述 本文介绍 E3 PAC 打包&#xff0c;编译器生成 bin 文件需要通过打包生成 PAC 包&#xff0c;再通过 SDToolBox 工具将 PAC 包烧写到芯片&#xff0c;PAC 包的物理载体分为 Flash、eMMC、SD&#xff0c;一个 PAC包最多支持 3 个BootPackage&#xff1b;本文主要描述打…

Maven 基础总结篇

Maven 基础总结篇 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; 提供了一套标准化的项目结构&#xff1a;用于解决不同IDE&#xff08;例如eclipse与IDEA&#xff09;不同的项目结构的问题 提供了一套标准化的构建流程&#xff08;编译&…

CMake入门教程【核心篇】动态库与静态库的差别

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.概述2.动态库(Shared Libraries)主要特点使用场景3.静态库(Static Libraries)主要特点

Android 13 移除下拉栏中的设置入口

介绍 因为当前项目的设置已被加密&#xff0c;客户不希望通过下拉窗口的设置图标进入设置&#xff0c;决定去掉该图标。 效果展示 分析 这里首先想到在SystemUI寻找这个图标的资源文件&#xff0c;找到资源文件后寻找对应控件调用的地方&#xff0c;根据id寻找控件代码即可。…

无锡市出租车数据,Shp+excel格式,2020年,字段含经纬度、采集时间、方向、各方向加速度等,可预览

基本信息. 数据名称: 无锡市出租车数据 数据格式: Shpexcel 数据时间: 2020年 数据几何类型: 点 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1id出租车id2lon经度_43263lat纬度_43264cjsj采集时间5fx方向6sd速…

vs2008 fatal error C1083: 无法打开包括文件:“atlapp.h”: No such file or directory

在翻看以前用vs2008写的代码时&#xff0c;竟然提示&#xff1a; fatal error C1083: 无法打开包括文件:“atlapp.h”: No such file or directory貌似以前也遇到过&#xff0c;至于具体原因一时忘记了。网上搜了一下&#xff0c;发现是因为没有安装WTL&#xff08;下载地址&am…

ffmpeg[学习(四)](代码实现) 实现音频数据解码并且用SDL播放

0、作者杂谈 CSDN大多数都是落后的&#xff0c;要么是到处复制粘贴的&#xff0c;对于初学者我来说困惑了很久&#xff0c;大多数CSDN文章都是使用旧的API &#xff0c;已经被否决了&#xff0c;于是我读一些官方文档&#xff0c;和一些开源项目音视频的输出过程&#xff0c;写…

PPT插件-大珩助手-选择同类

选择同类-颜色 对于选中的形状&#xff0c;一键选中当前页中的所有相同颜色的形状 选择同类-文本 一键选择当前页中的所有文本对象 选择同类-非文本 一键选择当前页中的所有非文本对象 选择同类-反选 一键选择当前页未选择的对象 软件介绍 PPT大珩助手是一款全新设计的…

C++协程操作

什么是C++协程 C++中的协程是一种用户态轻量级线程,它拥有自己的上下文和栈,并且协程的切换和调度由用户定义,不需要陷入内核。如同一个进程可以拥有多个线程,一个线程也可以拥有多个协程。协程的优点在于极高的执行效率,因为协程切换不需要陷入内核,而是由用户程序定义切…

国标gb28181模拟环境搭建

目录 准备工作服务器搭建模拟设备搭建注意事项:1.GB28181-2016模拟设备网络情况2.保证防火墙关闭3.按照我提供的方式安装wireshark 操作步骤1.打开GB28181-2016自动化测试工具2.运行界面配置3.GB28181-2016自动化测试工具运行4.打开模拟设备5.查看测试结果6.生成测试报告 抓包 …

用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

Retrieval-Augmented Generation&#xff08;RAG&#xff09;是一种强大的技术&#xff0c;能够提高大型语言模型&#xff08;LLM&#xff09;的性能&#xff0c;使其能够从外部知识源中检索信息以生成更准确、具有上下文的回答。 本文将详细介绍 RAG 在 LangChain 中的应用&a…