客户端的自动更新方案

  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 最近也解决了,更新本身这个问题。

猜你喜欢

转载自www.cnblogs.com/techdreaming/p/10988962.html