WPF客戶端自動升級


實現原理:通過一個輔助程序(更新程序.exe)比較本地版本號和服務器的版本,若服務器版本新則通過更新程序.exe下載服務器上資源(我是把最新的文件壓縮成zip放到服務器上)到本地進行替換。

 

服務器放置的升級文件結構如圖

 

  • 此時要有兩個程序,一個是自己的主程序,另一個是更新程序.exe,更新程序負責檢查版本號和下載更新,將更新程序放到主程序的目錄下。
  • 在主程序界面渲染顯示前,調用更新程序.exe進行版本檢查,如果有新版本則進行更新,沒有的話主程序繼續執行。
  • 此時本地和服務器應該有個相同的配置文件,用來存放一些必需的數據,我這里用的xml文件,讀取本地xml文件和服務器xml文件,比較版本信息(指的是主程序version和更新程序version)進而判斷需要升級主程序或者是升級程序亦或兩者都升級。
  • 如果發現主程序有新版本,啟用更新程序.exe從服務器上下載Debug.zip文件及xml文件,將zip壓縮包放到臨時文件夾下,利用第三方解壓庫CL.IO.Zip.dll進行解壓,解壓完成后將解壓得到的文件夾及文件遞歸復制到主程序目錄下,然后在更新程序中用Process.Start(主程序路徑)啟動主程序,主程序啟動成功則關閉更新程序.exe程序(可以通過殺進程操作),此時軟件已經升級成功。(這里我主程序只是做了版本比較,至於下載以及升級都交給更新程序.exe來做,當然也可以通過主程序進行下載,感覺有點分散了。。。)
  • 如果發現更新程序.exe有新版本,則直接在主程序中下載更新程序.exe進行替換即可。
  • 兩者都有最新版本,先按照第4步升級更新程序.exe,在按照第3步升級主程序。

 

部分壓縮包下載及解壓代碼: 

public class DownloadHelper
    {
        /// <summary>
        /// 獲取版本信息
        /// </summary>
        /// <param name="url">版本信息文件的url</param>
        /// <returns></returns>
        public static Tuple<bool,UpdateInfo> GetConfigInfo(string url)
        {
            try
            {
                if (string.IsNullOrEmpty(url))
                {
                    return new Tuple<bool, UpdateInfo>(false, null);
                }
                WebClient client = new WebClient();
                Stream s = client.OpenRead(new Uri(url));
                UpdateInfo info = XmlHelper.Instance.ReadVersionConfig(s);
                s.Close();
                return new Tuple<bool,UpdateInfo>(true,info);
            }
            catch (Exception)
            {
                return new Tuple<bool, UpdateInfo>(false, null);
            }
        }
        /// <summary>
        /// 解壓縮,拷貝,刪除
        /// </summary>
        /// <param name="sourcePath">zip的路徑</param>
        /// <param name="targetPath">目的路徑</param>
        /// <returns></returns>
        public static bool UnZip(string sourcePath, string targetPath)
        {
            try
            {
                string zipFile = Path.Combine(sourcePath, "temp.zip");
                string extractPath = Path.Combine(targetPath, "temp");
                if (!Directory.Exists(extractPath))
                {
                    Directory.CreateDirectory(extractPath);
                }
                ZipFile.ExtractToDirectory(zipFile, extractPath);//將zip文件拷貝到臨時文件夾
                if (Directory.Exists(Path.Combine(extractPath, "SeriesApp")))
                {
                    extractPath = Path.Combine(extractPath, "SeriesApp");
                }
                //將臨時文件夾下的文件復制到原程序路徑中
                CopyDirectory(extractPath, sourcePath);//注意,此時臨時文件夾為源地址,sourcePath為目標地址
                File.Delete(zipFile);//刪除zip文件
                Directory.Delete(Path.Combine(targetPath, "temp"), true);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 解壓縮,拷貝,刪除 
        /// </summary>
        /// <param name="sourcePath">zip的路徑</param>
        /// <param name="targetPath">目的路徑</param>
        /// <param name="pBar">ProgressBar顯示進度</param>
        /// <returns></returns>
        public static bool UnZip(string sourcePath, string targetPath,System.Windows.Controls.ProgressBar pBar)
        {
            try
            {
                ZipHandler handler = ZipHandler.GetInstance();
                string zipFile = Path.Combine(sourcePath, "temp.zip");
                string extractPath = Path.Combine(targetPath, "temp");
                handler.UnpackAll(zipFile, extractPath, (num) =>
                {
                    pBar.Dispatcher.Invoke(() =>
                    {
                        pBar.Value = num;//進度條顯示
                    });
                });
              
                if (Directory.Exists(Path.Combine(extractPath, "SeriesApp")))
                {
                    extractPath = Path.Combine(extractPath, "SeriesApp");
                }
                //將臨時文件夾下的文件復制到原程序路徑中
                CopyDirectory(extractPath, sourcePath);//注意,此時臨時文件夾為源地址,sourcePath為目標地址
                File.Delete(zipFile);//刪除zip文件
                Directory.Delete(Path.Combine(targetPath, "temp"), true);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        /// <summary>
        /// 下載zip文件
        /// </summary>
        /// <param name="zipUrl">zip的url</param>
        /// <param name="targetDirPath">目標文件夾路徑</param>
        /// <returns></returns>
        public static bool DownloadZip(string zipUrl,string targetDirPath)
        {
            string zipFile = Path.Combine(targetDirPath, "temp.zip");
            if (!Directory.Exists(targetDirPath))
            {
                return false;
            }
            try
            {
                WebClient client = new WebClient();
                client.DownloadFile(new Uri(zipUrl), zipFile);
                return true;
            }   
            catch (Exception)
            {
                return false;
            }
        }
        /// <summary>
        /// 下載xml配置
        /// </summary>
        /// <param name="url"></param>
        /// <param name="targetPath"></param>
        /// <returns></returns>
        public static bool DownLoadXMLConfig(string url, string targetPath)
        {
            try
            {
                var xmlPath = Path.Combine(targetPath, "VersionConfig.xml");
                WebClient client = new WebClient();
                client.DownloadFile(new Uri(url), xmlPath);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        /// <summary>
        /// 獲取Zip的總大小
        /// </summary>
        /// <param name="zipUrl"></param>
        /// <returns></returns>
        public static double GetZipTotalSize(string zipUrl)
        {

            try
            {
                WebClient client = new WebClient();
                byte[] sr = client.DownloadData(new Uri(zipUrl));
                return sr.Length;
            }
            catch (Exception)
            {
                return 0;
            }
        }
        /// <summary>
        /// 遞歸copy文件
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <param name="targetPath"></param>
        private static void CopyDirectory(string sourcePath, string targetPath)
        {
            try
            {
                if (!Directory.Exists(targetPath))
                {
                    Directory.CreateDirectory(targetPath);
                }
                string[] files = Directory.GetFiles(sourcePath);//Copy文件
                foreach (string file in files)
                {
                    try
                    {
                        string pFilePath = targetPath + "\\" + Path.GetFileName(file);
                        File.Copy(file, pFilePath, true);
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }

                string[] dirs = Directory.GetDirectories(sourcePath);//Copy目錄
                foreach (string dir in dirs)
                {
                    CopyDirectory(dir, targetPath + "\\" + Path.GetFileName(dir));
                }
            }
            catch (Exception ex)
            {

            }
            }
        }

 完整項目地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM