Visual Studio 发布程序自动更新 ClickOnce和AutoUpdater测试

2024-01-07 21:31:00

前言

虽然写的大部分都是不联网项目,上位机的项目一般写好了就不动了。但是说不定以后就需要自动更新呢。桌面程序不像网页,联网就能用。而是要进行版本号判断进行更新的。

运行环境

  • Visual Studio 2022
  • .net core 8.0
  • IIS

ClickOnce(Visual Studio 程序发布)

毕竟是微软官方的部署方式,应该是挺简单的

ClickOnce 安全性和部署

快速创建软件安装包-ClickOnce

在这里插入图片描述
在这里插入图片描述

IIS新建文件夹

在这里插入图片描述

C# 控制台测试

新建一个简单的控制台程序进行测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

安装测试

在这里插入图片描述

这里报错是因为没有签名。

在这里插入图片描述

在这里插入图片描述
安装成功,但是默认路径是C盘,有点尬尴

Choose install path for ClickOnce application during setup

在这里插入图片描述

更新测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

卸载

直接卸载即可

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

AutoUpdaterDotNET

AutoUpdater.NET github 仓库地址

AutoUpdater.NET 使用简介

在这里插入图片描述

在这里插入图片描述

实现原理

IIS
Update.html:更新日志详细信息的内容
AutoUpdateStarter.xml:版本号信息
Update.zip:程序压缩包,覆盖式安装

简单使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新建一个WPF项目

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Grid>
        <StackPanel>
            <TextBlock Text="版本1.0.1"
                       FontSize="50"
                       Name="LabelVersion" />
            <Button Content="按钮"  FontSize="30" Click="Button_Click"/>
        </StackPanel>

    </Grid>
</Window>

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            AutoUpdateTest();
        }

        public void AutoUpdateTest()
        {
            Assembly assembly = Assembly.GetEntryAssembly();
            LabelVersion.Text = $"Current Version : {assembly.GetName().Version}";//显示版本号
            AutoUpdater.AppTitle = "升级更新";
            Thread.CurrentThread.CurrentCulture =
                Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("zh");
            AutoUpdater.LetUserSelectRemindLater = true;
            AutoUpdater.RemindLaterTimeSpan = RemindLaterFormat.Minutes;
            AutoUpdater.RemindLaterAt = 1;
            AutoUpdater.ReportErrors = true;
            DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(2) };//定时去检测更新根据自己业务需求
            timer.Tick += delegate { AutoUpdater.Start("http://localhost:10911/Updates/AutoUpdaterStarter.xml"); };
            timer.Start();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            AutoUpdater.Start("http://localhost:10911/Updates/AutoUpdaterStarter.xml");
        }
    }

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

代码封装

这里用到了之前的代码

C# 自定义配置文件序列化生成+文件格式错误自动回档

   public class MyXmlConfigHelper<T>
   {
       public T Setting { get; set; }

       public string FileName { get; set; } = "MyConfig.xml";

       public string DirectoryPath
       {
           get
           {
               var regex = new Regex(@"\\(\w+)\.(\w+)$");
               return regex.Split(FullPath)[0];
           }
       }
       public string DebugPath { get => Directory.GetCurrentDirectory(); }

       public string FullPath { get => DebugPath + "\\" + FileName; }

       public bool IsFileExist { get => File.Exists(FullPath); }

       public bool IsDirectoryExist { get => Directory.Exists(DirectoryPath); }

       public Action<string> ShowMsg { get; set; } = (msg)=>Console.WriteLine(msg);

       public MyXmlConfigHelper()
       {

       }
       public MyXmlConfigHelper(string filename)
       {
           FileName = filename;
           if (!IsDirectoryExist)
           {
               DirectoryInfo directoryInfo = new DirectoryInfo(DirectoryPath);
               directoryInfo.Create();
           }
       }

       public MyXmlConfigHelper(T setting ,string filename):this(filename)
       {
           Setting = setting;
       }

       /// <summary>
       /// 创建文件
       /// </summary>
       public void Init()
       {
           if(IsFileExist)
           {
               try
               {
                   Read();
               }
               catch (Exception ex)
               {
                   ShowMsg(ex.ToString());
                   throw new Exception("文件读取失败!请确认是否配置文件格式是否正确");
               }
           }
           else
           {
               Write();
           }
       }

       /// <summary>
       /// 覆盖文件
       /// </summary>
       public void ReInit()
       {
           ShowMsg("正在覆盖配置文件:" + FullPath);
           Write();
       }
       /// <summary>
       /// 写入配置类
       /// </summary>
       private void Write()
       {
           ShowMsg("正在生成配置文件:" + FullPath);
           var xmlHelper = new XmlSerializer(typeof(T));
           using (StreamWriter xmlWriter = new StreamWriter(FullPath))
           {
               //去掉烦人的命名空间
               XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
               ns.Add("", "");
               xmlHelper.Serialize(xmlWriter, Setting, ns);
               xmlWriter.Close();
           }
       }

       /// <summary>
       /// 读取配置类
       /// </summary>
       private void Read()
       {
           ShowMsg("正在读取配置文件:"+FullPath);
           var xmlHelper = new XmlSerializer(typeof(T));
           using (StreamReader xmlReader = new StreamReader(FullPath))
           {
               
               Setting = (T)xmlHelper.Deserialize(xmlReader);
               xmlReader.Close();
           }
           
       }
   }

自动更新代码封装


  /// <summary>
  /// 自动更新帮助类
  /// </summary>
  public class AutoUpdateHelper
  {
      /// <summary>
      /// 更新地址
      /// </summary>
      public string UpdateLogUrl { get => BaseUrl + "Updates/UpdateLog.html"; }


      /// <summary>
      /// 网路基本路径
      /// </summary>
      public string BaseUrl { get; set; } = "http://localhost:10911/";

      /// <summary>
      /// Xml配置地址
      /// </summary>
      public string AutoXmlUrl { get => BaseUrl + "Updates/AutoUpdaterStarter.xml"; }

      /// <summary>
      /// 文件下载地址
      /// </summary>
      public string DownLoadUrl { get => BaseUrl + "DownLoads/Update.zip"; }


      /// <summary>
      /// Xml配置生成类
      /// </summary>
      public MyXmlConfigHelper<AutoUpdaterXmlEntity> MyXmlConfigHelper { get; set; } = new MyXmlConfigHelper<AutoUpdaterXmlEntity>(@"AutoUpdater\AutoUpdaterStarter.xml");

      /// <summary>
      /// 版本号
      /// </summary>
      public string VersionNo
      {
          get
          {
              Assembly assembly = Assembly.GetExecutingAssembly();
              return assembly.GetName().Version.ToString();
          }
      }

      /// <summary>
      /// 自动更新默认配置,Updates放配置文件,DownLoads放zip
      /// </summary>
      public AutoUpdateHelper()
      {
          AutoUpdater.AppTitle = $"升级更新";
          AutoUpdater.LetUserSelectRemindLater = true;
          AutoUpdater.RemindLaterTimeSpan = RemindLaterFormat.Minutes;
          AutoUpdater.RemindLaterAt = 1;
          AutoUpdater.ReportErrors = true;
      }
      /// <summary>
      /// 修改IIS网络地址,Updates放配置文件,DownLoads放zip
      /// </summary>
      /// <param name="url"></param>
      public AutoUpdateHelper(string url):this()
      {
          this.BaseUrl = url;
      }


      /// <summary>
      /// 自动更新程序
      /// </summary>
      public void Update()
      {
          AutoUpdater.Start(AutoXmlUrl);
      }


      /// <summary>
      /// 创建AutoXml文件
      /// </summary>
      public void CreateAutoXmlFile()
      {
          AutoUpdaterXmlEntity autoUpdaterXmlEntity = new AutoUpdaterXmlEntity()
          {
              Version = VersionNo,
              DownLoadUrl = DownLoadUrl,
              UpdateLogUrl = UpdateLogUrl
          };
          MyXmlConfigHelper.Setting = autoUpdaterXmlEntity;
          MyXmlConfigHelper.ReInit();
      }



  }

  /// <summary>
  /// 配置文件对应实体
  /// </summary>
  [XmlRoot("item")]
  public class AutoUpdaterXmlEntity
  {
      [XmlElement("version")]
      public string Version { get; set; }

      [XmlElement("url")]
      public string DownLoadUrl { get; set; }

      [XmlElement("changelog")]
      public string UpdateLogUrl { get; set; }

      [XmlElement("mandatory")]
      public string Mandatory { get; set; } = "false";
  }

简单使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结

还是AutoHelper好使,简单好用。AutoHelper的UpdateLog.html就自己加描述了,就是简单的html语言。

文章来源:https://blog.csdn.net/qq_44695769/article/details/135442440
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。