關於系統的自動更新。近日有一情況是需要將java端後台最新版本的系統檔案覆蓋本地用戶端,簡稱自動更新了。
本地會擷取當前系統的版本號碼去請求後台java的介面資料。返回給我的是後台壓縮包轉的base64位元組流。
用戶端拿到新版本需要更新本地程式。
if (UpdateSystem(Path.Combine(Application.StartupPath, "Version.txt"), Path.Combine(Application.StartupPath, "u.zip"))) { Application.Exit(); }
/// <summary> /// 讀取本地版本請求更新 /// </summary> /// <param name="document">讀取的檔案資訊</param> /// <param name="zipPath">返回zip包本地路徑</param> /// <returns></returns> private bool UpdateSystem(string document, string zipPath) { try { Dictionary<string, string> postDic = new Dictionary<string, string>(); //擷取檔案內的版本號碼 if(File.Exists(document)) { postDic.Add("version", File.ReadAllText(document).Trim()); } else { postDic.Add("version", "0"); } string postJson = JsonConvert.SerializeObject(postDic); string url = GetAppSettingValue("serverUrl") + "parkClient/parkClientUpdate"; //返回的json資料 JObject obj = (JObject)JsonConvert.DeserializeObject(PostData(postJson, url)); string newVersion = obj["version"].ToString(); if (!String.IsNullOrWhiteSpace(newVersion)) { byte[] bytesFile = Convert.FromBase64String(obj["byteArray"].ToString()); if (obj["clientMD5"].ToString() == BitConverter.ToString( new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(bytesFile)).Replace("-", "")) { ZipCoverage(bytesFile, zipPath); File.WriteAllText(document, newVersion); } } return true; } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } } /// <summary> /// 解壓zip包覆蓋更新 /// </summary> /// <param name="bytes">接受更新包的位元組資訊</param> /// <param name="zpath">覆蓋的路徑</param> private void ZipCoverage(byte[] bytes, string zpath) { File.WriteAllBytes(zpath, bytes); using (ZipArchive archive = ZipFile.OpenRead(zpath)) { string file = null; foreach (ZipArchiveEntry entry in archive.Entries) { if (!entry.FullName.EndsWith("/")) { file = Path.Combine(Application.StartupPath, entry.FullName); if (File.Exists(file)) { File.Delete(file); } } } } ZipFile.ExtractToDirectory(zpath, Application.StartupPath); } /// <summary> /// 擷取設定檔中的appSettings節中的配置內容 /// </summary> /// <param name="appSettingKey"></param> /// <param name="message"></param> /// <returns></returns> private string GetAppSettingValue(string appSettingKey) { ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = @"TDH.Parking.Client.exe.config" }; return ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None).AppSettings.Settings[appSettingKey].Value; }
byte[] bytesFile = Convert.FromBase64String(obj["byteArray"].ToString());
這裡是拿到的位元組流了。
這個方法可以解決在同一個解決方案中有多重專案可以讀取到同一個項目下的App.config檔案。
注意:其中有引用到的類庫, 這是是用來操作壓縮包的。
說下思路:第一步其實就是拿到壓縮包的位元組流再儲存到本地,第二步就是迴圈讀取壓縮包的檔案替換本地的檔案,完成本地系統的版本更新。
無論簡單與複雜,都需一步步向前方邁進。