window平台C#实现软件升级功能(控制台)

本文介绍了如何使用C#在Windows平台的控制台上实现可接收参数的软件升级功能,包括从Web获取新版本、验证、安装和重启程序的过程,以及使用Json处理接口返回的数据。
摘要由CSDN通过智能技术生成

 window平台C#实现软件升级功能

       之前用window窗体实现过一个升级功能,后来发现多个项目都需要升级功能,现改成可接收参数实现一种通用的exe.改用控制台方式实现这个升级功能,这样不仅实现了接收参数,升级程序体积也比原来的窗体形式更小。

一  Window窗体升级实现:

window平台C#实现软件升级功能(Window窗体应用)_开发电脑软件自动更新怎么实现-CSDN博客

 

二  控制台升级实现:

  1 关于升级细路,这里不再详细写,可参考上面Window窗体升级实现。

  2 完整C#控制台升级程序代码如下:

using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Runtime.InteropServices;
using System.Text.Json;
using System.Threading;

namespace ConsoleAppUpdate
{
    class Program
    {
        static String processName = "xxx应用";
        static String mainFilePath = "xxx应用.exe";
        static String infaceVersion = "";

       
        static String updateUrl = "https://xxx.xxx.xxx.xxx/pc/getLastApp";
        static String downloadUrlExe = "http://xxx.xxx.xxx.xx:89/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe";
        static String downloadFileName = "test.exe";

        // 导入 Windows API 函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);

        // 用visual studio 编译时 要配置
        static void Main(string[] args)
        {
            // 参数1 升级接口 url
            // 参数2 进程名称 用于关闭进程
            // 参数3 主文件名称 (不用指定目录,要求把升级文件放在主文件同一目录即可)
            if (args != null && args.Length > 1)
            {
                updateUrl = args[0];
                Log("rev update url = " + updateUrl);
            }
            else
            {
                Log("use default update url = " + updateUrl);
            }
            try
            {
                Update();
            }
            catch (Exception ee)
            {
                Log("update program Exception :" + ee.Message);

            }
            finally
            {
                Environment.Exit(0);
            }
        }



        //更新程序
        public static void Update()
        {
            Log("开始检测更新……");
            // 获取主程序的版本号
            String version = GetVersion(mainFilePath);

            // 检查是否有新版本
            String newVersion = GetVersionFromWeb();

            if (newVersion != null)
            {

                if ("0.0.0.0".Equals(version))
                {
                    Log("原主程序,直接更新.");
                    Log("开始下载…");
                    if (DownloadNewVersion())
                    {


                        // 安装新版本
                        Log("开始更新程序…");
                        InstallNewVersion();


                        Log("启动主程序…");
                        // 重启主程序
                        Process.Start(mainFilePath);
                        Log("启动主程序ok");

                    }
                    else
                    {
                        Log("因下载环节问题终止更新操作!");
                    }


                }
                else
                {
                    // 如果有新版本,则下载新版本
                    if (CompareVersion(newVersion, version) == 1)
                    {
                        Log("本地版本:" + version);

                        Log("符合更新条件,开始更新…");

                        Log("开始下载…");
                        if (DownloadNewVersion())
                        {

                            // 安装新版本
                            Log("开始更新程序…");
                            InstallNewVersion();


                            Log("启动主程序…");
                            // 重启主程序
                            Process.Start(mainFilePath);
                            Log("启动主程序ok");

                        }
                        else
                        {
                            Log("因下载环节问题终止更新操作!");
                        }

                    }
                    else
                    {
                        Log("没有的新条件,退出");
                    }
                }

            }
            else
            {
                Log("获取服务器版本失败!");
            }

            Log("更新程序退出.");

            Environment.Exit(0);

        }

        /// <summary>
        /// 下载新版本并验证版本号
        /// </summary>
        /// <returns></returns>
        private static Boolean DownloadNewVersion()
        {
            WebClient wcClient = new WebClient();


            // 下载文件并保存到指定位置
            WebClient client = new WebClient();
            Log("获取下载url: " + downloadUrlExe);

            byte[] data = client.DownloadData(downloadUrlExe);

            Log("下载文件大小[" + data.Length / 1024 + " kb]");

            String tempPath = "./" + downloadFileName;
            // 将字节数组保存到文件
            File.WriteAllBytes(tempPath, data);
            Log("保存位置 " + tempPath);


            //验证版本 是否与接口一致
            String version = GetVersion(tempPath);
            bool vaildVersion = version.Equals(infaceVersion);
            Log("验证已下载文件版本(" + version + ")与 接口版本(" + infaceVersion + "): " + vaildVersion);

            return vaildVersion;

        }


        /// <summary>
        /// 安装
        /// </summary>
        private static void InstallNewVersion()
        {

            Log("开始关闭主程序…");
            Process[] ppp = Process.GetProcessesByName(processName);
            if (ppp.Length > 0)
            {
                MessageBox(IntPtr.Zero, "正在执行升级,重启远程鉴定平台。", "升级提示", 0);
                try
                {
                    for (int i = 0; i < ppp.Length; i++)
                    {
                        Log("结束进程:" + ppp[i].ProcessName);
                        ppp[i].Kill();
                    }
                }
                catch (Exception ex)
                {
                    Log("结束进程异常:" + ex.Message);
                }


            }

            Log("备份主程序…");
            if (!Directory.Exists("./bak"))
            {
                Directory.CreateDirectory("./bak");
            }

            DateTime currentDateAndTime = DateTime.Now;
            String time = currentDateAndTime.ToString("yyyyMMddHHmmss");
            String bakPath = "./bak/" + mainFilePath + "." + time;

            if (File.Exists(mainFilePath))
            {
                File.Copy(mainFilePath, bakPath, true);
                Log("备份主程序完成。");

                int waitTimeMilliseconds = 1000; // 5秒
                Thread.Sleep(waitTimeMilliseconds);

                File.Delete(mainFilePath);
                Log("删除旧版程序OK。 ");
            }

            if (downloadFileName.EndsWith(".zip",StringComparison.CurrentCultureIgnoreCase))
            {
                //如果升级包是zip 先解压
                try
                {
                    // 解压zip文件到当前目录
                    ZipFile.ExtractToDirectory(downloadFileName, "./");
                    Console.WriteLine("Zip文件解压成功!");
                    File.Delete(downloadFileName);
                    Log("删除下载文件OK。 ");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("解压zip文件时出错:" + ex.Message);
                }

            }
            else
            {
                File.Copy(downloadFileName, mainFilePath);
                Log("更新主程序完成。");

                File.Delete(downloadFileName);
                Log("删除下载文件OK。 ");
            }

          


        }


        private static String GetVersionFromWeb()
        {
            Log("准备获取服务器版本号…");

            String json = request( updateUrl);

            //{"msg":"操作成功","code":200,"data":{"versionName":"1.0.0.1","updateContent":"test","fileSize":"107KB","url":"http://192.168.22.144:8904/common/downloadAppFile/2666c50a-6e1c-4a8a-b8f6-c1a5002d4ca0.exe","uploadTime":"2024-03-26 10:17:29"}}

            JsonElement element = JsonDocument.Parse(json).RootElement;

            infaceVersion = element.GetProperty("data").GetProperty("versionName").GetString();
            Log("获取服务器版本号:" + infaceVersion);

            downloadUrlExe = element.GetProperty("data").GetProperty("url").GetString();
            Log("获取服务器下载URL:" + downloadUrlExe);

            downloadFileName = element.GetProperty("data").GetProperty("saveName").GetString();
            Log("获取服务器下载文件名称:" + downloadFileName);

            return infaceVersion;
        }


        /// <summary>
        /// 日记记录
        /// </summary>
        /// <param name="v"></param>
        private static void Log(string v)
        {
    
            String filePath = "./update.log";
            try
            {
                using (StreamWriter writer = new StreamWriter(filePath, true))
                {
                    string logEntry = $"{DateTime.Now} - {v}";
                    writer.WriteLine(logEntry);
                }
            }
            catch (Exception ex)
            {
                // 记录异常信息
                Console.WriteLine("日志记录失败:" + ex.Message);
            }

        }

        /// <summary>
        /// http请求
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string request(string url)
        {
            using (WebClient client = new WebClient())
            {
                return client.DownloadString(url);
            }
        }

        /// <summary>
        /// 获取文件版本号
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static String GetVersion(string path)
        {
            Log("获取本地版本号……:" + path + "\n");

            if (!File.Exists(path))
            {
                string currentDirectory = Directory.GetCurrentDirectory();
                Console.WriteLine("Current Directory: " + currentDirectory);
                path = currentDirectory + "\\" + path;

                if (!File.Exists(path))
                {
                    Log("检测不到主文件,直接返回原始版本号");
                    return "0.0.0.0";
                }
            }

            // 获取文件版本信息
            FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(path);

            // 获取文件版本号
            string fileVersion = fileVersionInfo.FileVersion;

            Log("获取本地版本号:" + fileVersion + "\n");
            return fileVersion;
        }

        /// <summary>
        /// 比较软件的版本号
        /// </summary>
        /// <param name="version1"></param>
        /// <param name="version2"></param>
        /// <returns></returns>
        public static int CompareVersion(string version1, string version2)
        {
            string[] parts1 = version1.Split('.');
            string[] parts2 = version2.Split('.');

            for (int i = 0; i < parts1.Length && i < parts2.Length; i++)
            {
                int v1 = int.Parse(parts1[i]);
                int v2 = int.Parse(parts2[i]);

                if (v1 > v2)
                {
                    return 1;
                }
                else if (v1 < v2)
                {
                    return -1;
                }
            }

            return 0;
        }
    }
}

     因为升级是后台进行的,所以编译代码时 不要显示控制台,改一下:

  1. 打开 Visual Studio 中的项目。
  2. 在解决方案资源管理器中,右键单击项目,然后选择“属性”。
  3. 在属性窗口中,选择“应用程序”选项卡。
  4. 在“输出类型”下拉菜单中选择“Windows 应用程序”。
  5. 保存更改并重新构建项目。

如下图:

代码编译后,发现引用了很多dll,原因是因为升级接口返回的是json数据所以使用了一个json解析用到几个dll,需要复制到需要用到升级功能的项目即可。

实现效果图如下:

 

查看更新日记 

 

测试完美实现更新。 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qyhua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值