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

前言

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

运行环境

  • 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语言。

WPF (Windows Presentation Foundation)是一种用于创建Windows桌面应用程序的框架。WPF AutoUpdater是一个自动更新工具,用于在WPF应用程序中实现自动更新功能。 WPF AutoUpdater可以帮助开发人员将自动更新功能集成到他们的WPF应用程序中。它提供了一个简单的方式来检查和下载最新版本的应用程序,并自动安装更新。使用WPF AutoUpdater,用户无需手动下载和安装新版本,而是可以直接通过应用程序自动执行更新。 该工具的使用非常简单。开发人员只需在其WPF应用程序的代码中添加几行代码,即可实现自动更新功能。通过指定一个URL,这个URL将用于检查更新和下载最新版本的应用程序。WPF AutoUpdater还提供了一些选项,例如设置更新检查的时间间隔、设置是否在更新时显示进度条等。 WPF AutoUpdater的工作原理如下:首先,它会检查一个预先指定的URL,以确定是否有新版本可用。如果有新版本,WPF AutoUpdater将下载该版本到本地。然后,它会自动关闭当前应用程序,并启动一个更新程序,该程序将自动安装新版本的应用程序。安装完成后,更新程序将自动启动新版本的应用程序,以便用户可以立即体验更新后的功能。 WPF AutoUpdater的好处是它能够帮助开发人员提供更好的用户体验。通过自动更新功能,用户可以方便地获得最新的功能和修复bug,而不必手动下载和安装新版本。此外,开发人员可以在后台管理和控制更新过程,确保更新的顺利进行。 总之,WPF AutoUpdater是一个有用的工具,可以轻松实现WPF应用程序自动更新功能。它为开发人员和用户提供了便利,使应用程序的更新过程更加简单和高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值