客戶端的自動更新方案


  B/S架構的好處就是。UI代碼的修改只需要將新的html 文件部署在服務端即可。C/S 架構客戶端的修改就沒有那么方便了,需要每個客戶端一個一個的更新。這明顯是不可能的事情,有很多客戶端的時候,這種更新會要人命的。

  第一種方案:自動更新就是在客戶端啟動的時候檢測客戶端有沒有更新,有更新的話,下載新的客戶端文件,重新安裝就好。這種做法雖然比一個一個更新好多了,也減輕了實施人員的工作量,但是還是存在一個弊端,比如客戶端文件我就修改了一個xml ,都要下載整個客戶端文件進行重新安裝,這樣確實很浪費時間。

  第二種方案:就是按需更新,如果客戶端就需要更新一個xml 那就把xml文件放在服務端,客戶端檢測xml 文件有更新,只下載xml 文件即可。

  所以下面就說一下第二種更新方案。

  首先,服務端將客戶端目錄下所有文件的修改時間記錄,文件路徑,下來,定義一個版本號。,如果某一個文件有更新,那個這個文件的版本號就 + 1   。客戶端檢測的時候 首先將這個版本文件下載下來,對比本地的版本文件,看看哪一個文件的版本號碼有變化,那就是這個文件有更新。根據文件路徑只下載這個文件就好。

  文件發布:

  

 

 

try
            {
                XmlDocument xmlDoc = new XmlDocument();
                //Create the xml declaration first   
                xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null));
                //Create the root node and append into doc   
                var AutoUpdate = xmlDoc.CreateElement("AutoUpdate");
                xmlDoc.AppendChild(AutoUpdate);
                // Contact  
                XmlElement LastUpdateTime = xmlDoc.CreateElement("LastUpdateTime");
                //XmlAttribute attrID = xmlDoc.CreateAttribute("id");
                LastUpdateTime.InnerText = verModle.LastTime;
                AutoUpdate.AppendChild(LastUpdateTime);
                // Contact Name   
                XmlElement Version = xmlDoc.CreateElement("Version");
                Version.InnerText = verModle.Version;
                AutoUpdate.AppendChild(Version);

                XmlElement PubNumber = xmlDoc.CreateElement("PubNumber");
                PubNumber.InnerText = verModle.PubNumber;
                AutoUpdate.AppendChild(PubNumber);
                // Contact Gender   
                XmlElement UpdateFileList = xmlDoc.CreateElement("UpdateFileList");
                foreach (var item in verModle.fileDic)
                {
                    XmlElement File = xmlDoc.CreateElement("File");
                    XmlAttribute Ver = xmlDoc.CreateAttribute("Ver");
                    Ver.Value = item.Value.version;
                    File.Attributes.Append(Ver);
                    XmlAttribute LastTime = xmlDoc.CreateAttribute("LastTime");
                    LastTime.Value = item.Value.lastime;
                    File.Attributes.Append(LastTime);
                    XmlAttribute Name = xmlDoc.CreateAttribute("Name");
                    Name.Value = item.Key;
                    File.Attributes.Append(Name);
                    XmlAttribute pubnumber = xmlDoc.CreateAttribute("PubNumber");
                    pubnumber.Value = item.Value.pubnumber;
                    File.Attributes.Append(pubnumber);

                    UpdateFileList.AppendChild(File);
                }
                
                AutoUpdate.AppendChild(UpdateFileList);
                xmlDoc.Save(itemName + "_UpdateVersion.xml");
                if(File.Exists("BackUp/" + itemName + "_UpdateVersion.xml"))
                {
                    File.Delete("BackUp/" + itemName + "_UpdateVersion.xml");
                }
                File.Copy(itemName + "_UpdateVersion.xml", "BackUp/" + itemName + "_UpdateVersion.xml");
            }
            catch(Exception ex)
            {
                MessageBox.Show("發布失敗:" + ex.Message);
                return;
            }
            MessageBox.Show("發布成功:" + itemName + "_UpdateVersion.xml");

  文件檢測:

  

 

 

try
            {
                string root1 = AppDomain.CurrentDomain.BaseDirectory;
                DirectoryInfo di1 = new DirectoryInfo(root1);
                DirectoryInfo di2 = di1.Parent;
                string root = di2.FullName;
                LogClass.listLog.Add("root:" + root);
                //Directory.SetCurrentDirectory(root);
                bool update = false;
                int i = 0;
                foreach (var item in arrUpdate)
                {
                    int len = item.ToString().IndexOf("\\", 1);
                    len = len < 0 ? 0 : len;
                    string strItem = item.ToString().Substring(len);
                    //判斷是否是目錄
                    string ext = Path.GetExtension(strItem.ToString());
                    if (string.IsNullOrEmpty(ext))
                    {
                        try
                        {
                            if (!Directory.Exists(root + strItem))
                            {
                                Directory.CreateDirectory(root + strItem);
                                this.labelUpdatePath.Invoke((EventHandler)delegate
                                {
                                    labelUpdatePath.Text = strItem.ToString();
                                    //listBoxTip.Items.Add(item.ToString());
                                });
                            }
                        }
                        catch
                        {

                        }
                       
                    }
                    else
                    {
                        if(item.ToString().IndexOf("AutoUpdate.exe")>=0 &&
                            item.ToString().IndexOf("AutoUpdate.exe.config") < 0)
                        {
                            strItem = strItem + ".0";
                        }
                        bool ret = HttpHelper.HttpDownload(httpDownloadAddress + item.ToString(), root + strItem.ToString() + ".ttemp");
                        //bool ret = ftp.Download(root, item.ToString(),item.ToString().Substring(item.ToString().IndexOf("\\",1)));
                        if (ret)
                        {
                            this.labelUpdatePath.Invoke((EventHandler)delegate
                            {
                                labelUpdatePath.Text = strItem.ToString();
                            });
                        }
                        else
                        {
                            updateSuccess = false;
                            LogClass.listLog.Add("download file error:" + strItem.ToString());
                        }
                    }
                    i++;
                    this.progressBar1.Invoke((EventHandler)delegate
                    {
                        progressBar1.Value = i;
                    });
                    //listBoxTip.TopIndex = listBoxTip.Items.Count - 1;
                }
                this.Invoke((EventHandler)delegate
                {
                   
                    //開始刪除
                    bool ret = DealAfterUpdate(root);
                    if(!ret)
                    {
                        throw new Exception("DealAfterUpdate error");
                    }
                    if (File.Exists(root1 + "UpdateVersion.xml"))
                    {
                        File.Delete(root1 + "UpdateVersion.xml");
                    }
                    Thread.Sleep(100);
                    File.Move(root1 + updateFile, root1 + "UpdateVersion.xml");
                   
                    
                    if(File.Exists(root1 + "BackUp/UpdateVersion.xml"))
                    {
                        File.Delete(root1 + "BackUp/UpdateVersion.xml");
                    }
                    File.Copy(root1 + "UpdateVersion.xml", root1 + "BackUp/UpdateVersion.xml");
                    //操作完成之后,在啟動之前看看還是否需要有其他操作要執行
                    foreach(string item in excuteAfterUpdate.Split(','))
                    {
                        if (!string.IsNullOrEmpty(item))
                        {
                            LogClass.listLog.Add("ExcuteUpdate:" + root1 + item);
                            Process process = new Process();
                            process.StartInfo.FileName = root1 + item;   
                            process.StartInfo.Arguments = "";
                            process.Start();
                            process.WaitForExit();
                        }
                    }
                    if (isStartAfterUpdate == "1")
                    {
                        Process.Start(root1 + updateProcessPath);
                    }
                    if (this.args[0] == "1")
                    {
                        MessageBox.Show("更新完成");
                    }
                    this.Close();
                });
            }
            catch (Exception e)
            {
                this.Invoke((EventHandler)delegate
                {
                    MessageBox.Show("更新失敗");
                });
                LogClass.listLog.Add("thread error:" + e.Message);
            }
            updating = false;
        

  並且該自動更新插件,不挑剔任何客戶端,只要哪個客戶端需要自動更新,那就很方便的可以集成進去,已經運用在實際項目中,解決了很多復雜的工作。

  同時呢,自動更新exe 最近也解決了,更新本身這個問題。

 


免責聲明!

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



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