C# winform自動更新程序掃盲

http://bbs.bccn.net/viewthread.php?tid=428255&extra=page%3D1%26amp%3Bfilter%3Ddigest&page=1

自動更新 我直接簡單明瞭的說乾的 虛的就不整那麼多了,類似這樣
思路是一個客戶端一個主程序exe 自動更新程序exe 上圖

這是自動更新是單獨的一個exe 可能有童鞋要問 爲啥子是單獨一個exe呢 俺的思路是這樣 這個exe根據版本號從服務端下載程序 下載完成後 替換主程序的exe 並重新啓動主程序exe
看看這個autoupdate的代碼吧 
主要如下 這裏提供一個思路

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Update;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
namespace autoUpdate
{
    public partial class Form1 : Form
    {
        [DllImport("zipfile.dll")]
        public static extern int MyZip_ExtractFileAll(string zipfile, string pathname);
        public Form1()
        {
            InitializeComponent();

            //清除之前下載來的rar文件
            if (File.Exists(Application.StartupPath + "\\Update_autoUpdate.rar"))
            {
                try
                {
                    File.Delete(Application.StartupPath + "\\Update_autoUpdate.rar");
                }
                catch (Exception)
                {


                }

            }
            if (Directory.Exists(Application.StartupPath + "\\autoupload"))
            {
                try
                {
                    Directory.Delete(Application.StartupPath + "\\autoupload", true);
                }
                catch (Exception)
                {


                }
            }
           
            //檢查服務端是否有新版本程序
            checkUpdate();
            timer1.Enabled = true;
        }

        SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "xinDianClient");
        public void checkUpdate()
        {

            app.UpdateFinish += new UpdateState(app_UpdateFinish);
            try
            {
                if (app.IsUpdate)
                {
                    app.Update();
                }
                else
                {
                    MessageBox.Show("未檢測到新版本!");
                    Application.Exit();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void app_UpdateFinish()
        {
            //解壓下載後的文件
            string path = app.FinalZipName;
            if (File.Exists(path))
            {
                 //後改的 先解壓濾波zip植入ini然後再重新壓縮
                string dirEcgPath = Application.StartupPath + "\\" + "autoupload";
                if (!Directory.Exists(dirEcgPath))
                {
                    Directory.CreateDirectory(dirEcgPath);
                }
                //開始解壓壓縮包
                MyZip_ExtractFileAll(path, dirEcgPath);

                try
                {
                    //複製新文件替換舊文件
                    DirectoryInfo TheFolder = new DirectoryInfo(dirEcgPath);
                    foreach (FileInfo NextFile in TheFolder.GetFiles())
                    {
                        File.Copy(NextFile.FullName, Application.StartupPath + "\\program\\" + NextFile.Name,true);
                    }
                    Directory.Delete(dirEcgPath,true);
                    File.Delete(path);
                    //覆蓋完成 重新啓動程序
                    path = Application.StartupPath + "\\program";
                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName = "xinDianClient.exe";
                    process.StartInfo.WorkingDirectory = path;//要掉用得exe路徑例如:"C:\windows";               
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();

                    Application.Exit();
                }
                catch (Exception)
                {
                    MessageBox.Show("請關閉系統在執行更新操作!");
                    Application.Exit();
                }

               
            
               
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label2.Text = "下載文件進度:" + COMMON.CommonMethod.autostep.ToString() + "%";
            if (COMMON.CommonMethod.autostep==100)
            {
                timer1.Enabled = false;
            }
        }

    }
}


簡單的說就是檢查服務端的是否有新版本 然後呢 下載到本地 並替換在打開 


SoftUpdate是一個下載操作類

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

namespace Update
{
    /// <summary>  
    /// 更新完成觸發的事件  
    /// </summary>  
    public delegate void UpdateState();
    /// <summary>  
    /// 程序更新  
    /// </summary>  
    public class SoftUpdate
    {

        private string download;
        private const string updateUrl = "http://33.8.11.117:8019/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; }
        }

        private string _finalZipName = string.Empty;

        public string FinalZipName
        {
            get { return _finalZipName; }
            set { _finalZipName = value; }
        }

        #endregion

        /// <summary>  
        /// 更新完成時觸發的事件  
        /// </summary>  
        public event UpdateState UpdateFinish;
        private void isFinish()
        {
            if (UpdateFinish != null)
                UpdateFinish();
        }

        /// <summary>  
        /// 下載更新  
        /// </summary>  
        public void Update()
        {
            try
            {
                if (!isUpdate)
                    return;
                WebClient wc = new WebClient();
                string filename = "";
                string exten = download.Substring(download.LastIndexOf("."));
                if (loadFile.IndexOf(@"\") == -1)
                    filename = "Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;
                else
                    filename = Path.GetDirectoryName(loadFile) + "\\Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;

                FinalZipName = filename;
                //wc.DownloadFile(download, filename);
                wc.DownloadFileAsync(new Uri(download), filename);
                wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                wc.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                //wc.Dispose();
             
            }
            catch
            {
                throw new Exception("更新出現錯誤,網絡連接失敗!");
            }
        }

        void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            (sender as WebClient).Dispose();
            isFinish();
        }

        void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            CommonMethod.autostep = e.ProgressPercentage;
        }

        /// <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;
        }
    }
}

OK 下載的exe寫完了 現在呢客戶端還差一點就是要在主程序中嵌入它
主程序呢我是這樣寫的 請不懂的騷年看主要代碼
 [STAThread]
        static void Main()
        {
            if (checkUpdateLoad())
            {
                Application.Exit();
                return;
            }
            //執行打開主窗體之類的代碼。。。。
        }   

        public static  bool checkUpdateLoad()
        {
            bool result = false;
            SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "xinDianClient");
            try
            {
                if (app.IsUpdate && MessageBox.Show("檢查到新版本,是否更新?", "版本檢查", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    string path = Application.StartupPath.Replace("program", "");
                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName = "autoUpdate.exe";
                    process.StartInfo.WorkingDirectory = path;//要掉用得exe路徑例如:"C:\windows";               
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();

                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                result = false;
            }
            return result;
        }

啓動main函數的時候 檢查服務端是否有更新 結合SoftUpdate類看就一目瞭然了 要特別注意目錄 爲啥子這樣說呢 因爲有的dll要公用 正在使用就無法替換 所以要分開 
所以我的做法是 把主程序放到一個目錄 自動更新在外部 


[assembly: AssemblyVersion("1.0.0.3")]
[assembly: AssemblyFileVersion("1.0.0.3")]

還有特別要注意的一點 因爲要速度嘛 我索性用了.net自帶的版本控制 當然也可以自己寫 
主要在這裏 要特別注意一下 


OK 現在要部署服務端了 服務端呢 是個zip 我用的zipfile 進行壓縮和解壓縮的 
所以要在服務端部署 最好用這個dll生成一個壓縮包
然後部署在服務端iis服務器中 

rar 是更新程序 包括要更新的 exe dll之類的
<?xml version="1.0" encoding="utf-8" ?>  
<Update> 
   <Soft Name="update"> 
     <Verson>1.0.0.3</Verson>  
     <DownLoad>http://33.8.11.117:8079/update.rar</DownLoad>  
  </Soft> 
</Update> 

xml內容 一看都明白了把 下載地址 軟件名次 版本號


發佈了58 篇原創文章 · 獲贊 102 · 訪問量 67萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章