c/s 自動升級(WebService)


首先聲明,本人文筆不好,大家見笑,歡迎高手吐槽.

做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));
            }
        }
View Code

下載方式有很多,這里已經有了文件的下載地址,下載代碼大家就盡情發揮.有什么好的方式也告訴我一下,非常感謝

 

運行截圖

基本上就完了.歡迎高手吐槽.

很多朋友說dll文件無法下載,本人測試時沒問題的.

還有其他特殊文件如cs,config.這里提供2中解決方案

1.先壓縮,下載完后解壓

2.改后綴,什么后綴隨意,只要排除特殊不能下載的后綴

 源碼地址:http://download.csdn.net/detail/fenglove123/6031397


免責聲明!

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



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