首先聲明,本人文筆不好,大家見笑,歡迎高手吐槽.
做c/s開發肯定會遇到的就是自動升級功能,而這實現方式是非常多. 本文使用 webservice的方式來提供升級服務
首先准備服務
為了方便我們專門用一個文件夾來存放需要更新的應用程序
因為覺得通過新版本來更新很麻煩,所以驗證文件是否需要更新用md5來判斷
WebService:
public string GetVer() { DirectoryInfo dir = new DirectoryInfo(Server.MapPath("update")); var list = new List<object>(); var url = string.Format("http://{0}:{1}/update/", HttpContext.Current.Request.Url.Host, HttpContext.Current.Request.Url.Port); DirectoryInfoHelper.SetDirectoryInfo(dir, list, url, ""); JavaScriptSerializer json = new JavaScriptSerializer(); return json.Serialize(list); }
相關方法:
public static void SetDirectoryInfo(DirectoryInfo dir, List<object> list, string url, string dirName) { foreach (var file in dir.GetFiles()) { FileStream fs = File.OpenRead(file.FullName); list.Add(new { file.Name, Md5 = Security.GetMd5(fs), LocalHost = url, Directory = dirName }); fs.Close(); } foreach (var dirInfo in dir.GetDirectories()) { SetDirectoryInfo(dirInfo, list, url, string.Format("{0}{1}/", dirName, dirInfo.Name)); } }
說明:1.不創建模型,而服務端只需要提供數據,所以采用匿名對象
2.GetVer服務返回信息中 包含 文件名,md5值,域名地址,該文件上級目錄
C/S:
先看界面
現在就跟着提示消息走吧.
1.獲取服務文件特征
調用webservice獲取文件信息
private List<VerMd5Date> GetServerData() { AutoUpdate.Update update = new AutoUpdate.Update(); var json = update.GetVer(); var list = AppCode.JsonHelper.JsonDeserialize<VerMd5Dates>(json); return list; }
客戶端需要反序列化json 所以建了一個對應model
public class VerMd5Date { public string Name { get; set; } public string Md5 { get; set; } public string LocalHost { get; set; } public string Directory { get; set; } } class VerMd5Dates : List<VerMd5Date> { }
反序列化:
/// <summary> /// 反序列化json /// </summary> /// <typeparam name="T">對象</typeparam> /// <param name="jsonString">json字符串</param> public static T JsonDeserialize<T>(string jsonString) { DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)ser.ReadObject(ms); return obj; }
2.獲取本地文件特征
private List<VerMd5Date> GetLocalData(List<string> serverNames) { DirectoryInfo dir = new DirectoryInfo(Application.StartupPath); var list = new List<VerMd5Date>(); DirectoryInfoHelper.GetDirectoryInfo(dir, list,"",serverNames); return list; }
相關方法:
public static void GetDirectoryInfo(DirectoryInfo dir, List<VerMd5Date> list, string dirName, List<string> serverNames) { foreach (var file in dir.GetFiles().Where(m=>serverNames.Contains(dirName+m.Name))) { using (FileStream fs = File.OpenRead(file.FullName)) { list.Add(new VerMd5Date { Name = file.Name, Directory = dirName, Md5 = Security.GetMd5(fs) }); } } foreach (var dirInfo in dir.GetDirectories()) { GetDirectoryInfo(dirInfo, list, string.Format("{0}{1}/", dirName, dirInfo.Name), serverNames); } }
說明:serverNames 是服務器文件名集合,主要用來排除本地文件夾中非本程序文件
3.對比文件差異
private List<VerMd5Date> EqualsList(List<VerMd5Date> list, List<VerMd5Date> localList) { var getList = new List<VerMd5Date>(); foreach (var ver in list) { var file = localList.FirstOrDefault(m => m.Name == ver.Name && m.Directory == ver.Directory); if (file == null) { getList.Add(ver); } else { if (file.Md5 != ver.Md5 && file.Directory == ver.Directory) { getList.Add(ver); } } } return getList; }
4.下面就開始下載吧
foreach (var file in _getList) { SetItem(string.Format("正在下載 {0}{1}", file.Directory, file.Name)); DownloadFile(file.LocalHost, file.Directory, file.Name, progressBar1); }
DownloadFile:

public void DownloadFile(string localHost, string dirName, string filename, ProgressBar prog) { try { WebRequest rq = WebRequest.Create(string.Format("{0}{1}{2}", localHost, dirName, filename)); WebResponse rp = rq.GetResponse(); if (prog != null) { SetProg((int) rp.ContentLength, 1); } string path = string.Format("{0}/{1}", Application.StartupPath, dirName); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } Stream newFile = File.Create(string.Format("{0}{1}", dirName, filename)); Stream serviceFile = rp.GetResponseStream(); if (serviceFile == null) return; long totalDownloadedByte = 0; byte[] by = new byte[102400]; int osize = serviceFile.Read(by, 0, by.Length); while (osize > 0) { if (!cbCpu.Checked) Thread.Sleep(1); newFile.Write(by, 0, osize); osize = serviceFile.Read(by, 0, by.Length); if (prog == null) continue; totalDownloadedByte = osize + totalDownloadedByte; SetProg((int) totalDownloadedByte, 2); } newFile.Close(); serviceFile.Close(); SetItem("下載完成"); } catch(Exception e) { SetItem(string.Format("---程序異常:{0}", e.Message)); } }
下載方式有很多,這里已經有了文件的下載地址,下載代碼大家就盡情發揮.有什么好的方式也告訴我一下,非常感謝
運行截圖
基本上就完了.歡迎高手吐槽.
很多朋友說dll文件無法下載,本人測試時沒問題的.
還有其他特殊文件如cs,config.這里提供2中解決方案
1.先壓縮,下載完后解壓
2.改后綴,什么后綴隨意,只要排除特殊不能下載的后綴