winform版本自動更新

咱們在使用軟件的時候常常會遇到升級版本,這也是Winform程序的一個功能,今天就大概說下我是怎麼實現的吧(代碼有點不完美有小BUG,後面再說)node

先說下個人思路:首先在打開程序的時候去拿到我以前在網站上寫好的xml裏邊的版本號,判斷是否要更新,以後要更新的話就調用更新的exe(ps:這個是單獨出來的,由於更新確定要覆蓋當前的文件,文件運行的時候不能被覆蓋),而後下載最新的壓縮包到本地,調用7z解壓覆蓋便可服務器

思路明確了以後就開始寫代碼(因此說思路很重要啊!!!):
網絡

<?xml version="1.0" encoding="utf-8" ?>
<Update>
  <Soft Name="BlogWriter">
    <Verson>1.0.1.2</Verson>
    <DownLoad>http://www.shitong666.cn/BlogWrite.zip</DownLoad>
  </Soft>
</Update>

這是xml,先放到服務器上去app

檢查更新的代碼(我把這個封裝成了一個類):ide

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Net;
using System.Xml;

namespace UpdateDemo
{

    /// <summary>  
    /// 程序更新  
    /// </summary>  
    public class SoftUpdate
    {

        private string download;
        private const string updateUrl = "http://www.shitong666.cn/update.xml";//升級配置的XML文件地址  

        #region 構造函數
        public SoftUpdate() { }

        /// <summary>  
        /// 程序更新  
        /// </summary>  
        /// <param name="file">要更新的文件</param>  
        public SoftUpdate(string file, string softName)
        {
            this.LoadFile = file;
            this.SoftName = softName;
        }
        #endregion

        #region 屬性
        private string loadFile;
        private string newVerson;
        private string softName;
        private bool isUpdate;

        /// <summary>  
        /// 或取是否須要更新  
        /// </summary>  
        public bool IsUpdate
        {
            get
            {
                checkUpdate();
                return isUpdate;
            }
        }

        /// <summary>  
        /// 要檢查更新的文件  
        /// </summary>  
        public string LoadFile
        {
            get { return loadFile; }
            set { loadFile = value; }
        }

        /// <summary>  
        /// 程序集新版本  
        /// </summary>  
        public string NewVerson
        {
            get { return newVerson; }
        }

        /// <summary>  
        /// 升級的名稱  
        /// </summary>  
        public string SoftName
        {
            get { return softName; }
            set { softName = value; }
        }

        #endregion

        /// <summary>  
        /// 檢查是否須要更新  
        /// </summary>  
        public void checkUpdate()
        {
            try
            {
                WebClient wc = new WebClient();
                Stream stream = wc.OpenRead(updateUrl);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(stream);
                XmlNode list = xmlDoc.SelectSingleNode("Update");
                foreach (XmlNode node in list)
                {
                    if (node.Name == "Soft" && node.Attributes["Name"].Value.ToLower() == SoftName.ToLower())
                    {
                        foreach (XmlNode xml in node)
                        {
                            if (xml.Name == "Verson")
                                newVerson = xml.InnerText;//拿到最新版本號
                            else
                                download = xml.InnerText;//拿到要更新的文件(這塊不用拿的,懶得改了)
                        }
                    }
                }

                Version ver = new Version(newVerson);
                Version verson = Assembly.LoadFrom(loadFile).GetName().Version;
                int tm = verson.CompareTo(ver); //版本號比較
                if (tm >= 0)
                    isUpdate = false;
                else
                    isUpdate = true;
            }
            catch (Exception ex)
            {
                throw new Exception("更新出現錯誤,請確認網絡鏈接無誤後重試!");
            }
        }

        /// <summary>  
        /// 獲取要更新的文件  
        /// </summary>  
        /// <returns></returns>  
        public override string ToString()
        {
            return this.loadFile;
        }
    }
}

而後在主程序裏調用這個這檢查更新:函數

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Text = "Hello(版本1.0)";
            label1.Text = "Hello World  1.0";

         
            checkUpdate();//檢查更新
        }


        public void checkUpdate()
        {
            SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "BlogWriter");
            try
            {
                if (app.IsUpdate && MessageBox.Show("檢查到新版本,是否更新?", "Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                     //更新(調用更新的exe,這個是單獨的一個程序,下面再說怎麼寫)
                    string fileName = Application.StartupPath+@"\Updata.exe";
                    Process p = new Process();
                    p.StartInfo.UseShellExecute = false;
                    p.StartInfo.RedirectStandardOutput = true;
                    p.StartInfo.FileName = fileName;
                    p.StartInfo.CreateNoWindow = true;
                    p.StartInfo.Arguments = "你好, 西安 歡迎你!";//參數以空格分隔,若是某個參數爲空,能夠傳入」」
                    p.Start();
           System.Environment.Exit(System.Environment.ExitCode);   //結束主線程
          // p.WaitForExit(); //這裏就不能等他結束了
           //
string output = p.StandardOutput.ReadToEnd(); //this.Dispose();//關閉主程序
               
} } catch (Exception ex) { MessageBox.Show(ex.Message); } } }

下來就是下載更新的壓縮包了和解壓的exe了:優化

先看界面網站

    public partial class UpdateForm : Form
    {
        public UpdateForm()
        {
            InitializeComponent();

            this.button1.Enabled = false;
            this.button1.Click += button1_Click;
            this.Text = "更新...";
            UpdateDownLoad();
            // Update();
        }

        void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        public delegate void ChangeBarDel(System.Net.DownloadProgressChangedEventArgs e);

        private void UpdateDownLoad()
        {
            WebClient wc = new WebClient();
            wc.DownloadProgressChanged += wc_DownloadProgressChanged;
            wc.DownloadFileAsync(new Uri("http://www.shitong666.cn/BlogWriter.zip"), "Update.zip");//要下載文件的路徑,下載以後的命名
        }
         //  int index = 0;
        void wc_DownloadProgressChanged(object sender, System.Net.DownloadProgressChangedEventArgs e)
        {
            Action act = () =>
            {
                this.progressBar1.Value = e.ProgressPercentage;
                this.label1.Text = e.ProgressPercentage + "%";

            };
            this.Invoke(act);

            if (e.ProgressPercentage == 100)
            {
                //下載完成以後開始覆蓋
                
                  ZipHelper.Unzip();//調用解壓的類
                this.button1.Enabled = true;

            }
        }
    }

解壓的類:this

    public class ZipHelper
    {
        public static string zipFileFullName = "update.zip";
        public static void Unzip()
        {
            string _appPath = new DirectoryInfo(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName).Parent.FullName;

            string s7z = _appPath + @"\7-Zip\7z.exe";
            System.Diagnostics.Process pNew = new System.Diagnostics.Process();
            pNew.StartInfo.FileName = s7z;
            pNew.StartInfo.Arguments = string.Format(" x \"{0}\\{1}\" -y -o\"{0}\"", _appPath, zipFileFullName);
            //x "1" -y -o"2" 這段7z命令的意思: x是解壓的意思 "{0}"的位置寫要解壓文件路徑"{1}"這個1的位置寫要解壓的文件名 -y是覆蓋的意思 -o是要解壓的位置
            pNew.Start();
            //等待完成
            pNew.WaitForExit();
       //刪除壓縮包
           File.Delete(_appPath + @"\" + zipFileFullName); } }

 

最後說bug吧!這個bug真心多,首先我拿不到解壓的進度,個人想法是讓更新的進度條停在90%左右等待解壓完成以後再走到100%,其他的再優化一下就應該能夠用了,最後謝謝hover大神給個人指導spa

相關文章
相關標籤/搜索