C# web系统自动更新设计与实现

业务需求:BS架构系统的在线更新,实现文件在线校验更新及数据库在线更新。

下面简单写一下思路及实现,整体需包含校验文件及目录配置,文件MD5码校验,文件下载等。其中dll文件的更新需要注意

很多代码是从网上搜来的,项目也没有仔细整理,哪些有用哪些没用也忘记了,干脆全部贴出来,将就着看吧

文件下载类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Threading.Tasks;

namespace YS.Update
{
    public class DownFile
    {
        //从服务器下载文件,若目录存在,直接复制新文件,不存在则新建目录并复制文件,成功后返回1
        public bool DownFileFromServ(string url, string fileName)
        {
            bool downsucess = false;
            try
            {
                string fileExtraName = url.Split(char.Parse("."))[0];                              //文件名
                string fileAfterName = System.IO.Path.GetExtension(url);                //文件的扩展名
                if (fileAfterName == ".aspx")
                    url = fileAfterName + ".txt";
                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
                myReq.KeepAlive = true;
                HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();

                downsucess = this.CopyFileAndDirectory(myRes, fileName);

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            return downsucess;
        }

        //返回复制文件或创建目录是否成功
        public bool CopyFileAndDirectory(WebResponse myResp, string fileName)
        {
            bool flag = true;
            byte[] buffer = new byte[0x400];
            try
            {
                int num;
                //若本身已有该目录则删除
                if (System.IO.File.Exists(fileName))
                {
                    System.IO.File.Delete(fileName);
                }
                //创建目录更新到Updat目录下
                string directoryName = Path.GetDirectoryName(fileName);
                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }

                //指定文件fileName不存在时创建它
                Stream streamRead = System.IO.File.Open(fileName, FileMode.Create);

                Stream responseStream = myResp.GetResponseStream();

                do
                {
                    //从当前读取的字节流数,复制
                    num = responseStream.Read(buffer, 0, buffer.Length);
                    if (num > 0)
                    {
                        streamRead.Write(buffer, 0, num);
                    }
                }
                while (num > 0);
                streamRead.Close();
                responseStream.Close();
            }
            catch
            {
                flag = false;
            }

            return flag;

        }

    }
}

filehelper

using System;
using System.Text;
using System.IO; 

namespace YS.Update
{
    public static class FileHelper
    {
        #region 检测指定目录是否存在
        /// <summary>  
        /// 检测指定目录是否存在  
        /// </summary>  
        /// <param name="directoryPath">目录的绝对路径</param>          
        public static bool IsExistDirectory(string directoryPath)
        {
            return Directory.Exists(directoryPath);
        }
        #endregion

        #region 检测指定文件是否存在
        /// <summary>  
        /// 检测指定文件是否存在,如果存在则返回true。  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static bool IsExistFile(string filePath)
        {
            return File.Exists(filePath);
        }
        #endregion

        #region 检测指定目录是否为空
        /// <summary>  
        /// 检测指定目录是否为空  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>          
        public static bool IsEmptyDirectory(string directoryPath)
        {
            try
            {
                //判断是否存在文件  
                string[] fileNames = GetFileNames(directoryPath);
                if (fileNames.Length > 0)
                {
                    return false;
                }

                //判断是否存在文件夹  
                string[] directoryNames = GetDirectories(directoryPath);
                return directoryNames.Length <= 0;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region 检测指定目录中是否存在指定的文件
        /// <summary>  
        /// 检测指定目录中是否存在指定的文件,若要搜索子目录请使用重载方法.  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        /// <param name="searchPattern">模式字符串,"*"代表0或N个字符,"?"代表1个字符。  
        /// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>          
        public static bool Contains(string directoryPath, string searchPattern)
        {
            try
            {
                //获取指定的文件列表  
                string[] fileNames = GetFileNames(directoryPath, searchPattern, false);

                //判断指定文件是否存在  
                return fileNames.Length != 0;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>  
        /// 检测指定目录中是否存在指定的文件  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        /// <param name="searchPattern">模式字符串,"*"代表0或N个字符,"?"代表1个字符。  
        /// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>   
        /// <param name="isSearchChild">是否搜索子目录</param>  
        public static bool Contains(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                //获取指定的文件列表  
                string[] fileNames = GetFileNames(directoryPath, searchPattern, true);

                //判断指定文件是否存在  
                return fileNames.Length != 0;
            }
            catch
            {
                return false;
            }
        }
        #endregion

        #region 创建一个目录
        /// <summary>  
        /// 创建一个目录  
        /// </summary>  
        /// <param name="directoryPath">目录的绝对路径</param>  
        public static void CreateDirectory(string directoryPath)
        {
            //如果目录不存在则创建该目录  
            if (!IsExistDirectory(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
        }
        #endregion

        #region 创建一个文件
        /// <summary>  
        /// 创建一个文件。  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        public static bool CreateFile(string filePath)
        {
            try
            {
                //如果文件不存在则创建该文件  
                if (!IsExistFile(filePath))
                {
                    //创建一个FileInfo对象  
                    FileInfo file = new FileInfo(filePath);
                    //创建文件  
                    FileStream fs = file.Create();
                    //关闭文件流  
                    fs.Close();
                }
            }
            catch
            {
                return false;
            }

            return true;
        }

        /// <summary>  
        /// 创建一个文件,并将字节流写入文件。  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        /// <param name="buffer">二进制流数据</param>  
        public static bool CreateFile(string filePath, byte[] buffer)
        {
            try
            {
                //如果文件不存在则创建该文件  
                if (!IsExistFile(filePath))
                {
                    //创建一个FileInfo对象  
                    FileInfo file = new FileInfo(filePath);

                    //创建文件  
                    FileStream fs = file.Create();

                    //写入二进制流  
                    fs.Write(buffer, 0, buffer.Length);

                    //关闭文件流  
                    fs.Close();
                }
            }
            catch
            {
                return false;
            }
            return true;
        }
        #endregion

        #region 获取文本文件的行数
        /// <summary>  
        /// 获取文本文件的行数  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static int GetLineCount(string filePath)
        {
            //将文本文件的各行读到一个字符串数组中  
            string[] rows = File.ReadAllLines(filePath);

            //返回行数  
            return rows.Length;
        }
        #endregion

        #region 获取一个文件的长度
        /// <summary>  
        /// 获取一个文件的长度,单位为Byte  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static int GetFileSize(string filePath)
        {
            //创建一个文件对象  
            FileInfo fi = new FileInfo(filePath);

            //获取文件的大小  
            return (int)fi.Length;
        }

        /// <summary>  
        /// 获取一个文件的长度,单位为KB  
        /// </summary>  
        /// <param name="filePath">文件的路径</param>          
        public static double GetFileSizeByKB(string filePath)
        {
            //创建一个文件对象  
            FileInfo fi = new FileInfo(filePath);
            long size = fi.Length / 1024;
            //获取文件的大小  
            return double.Parse(size.ToString());
        }

        /// <summary>  
        /// 获取一个文件的长度,单位为MB  
        /// </summary>  
        /// <param name="filePath">文件的路径</param>          
        public static double GetFileSizeByMB(string filePath)
        {
            //创建一个文件对象  
            FileInfo fi = new FileInfo(filePath);
            long size = fi.Length / 1024 / 1024;
            //获取文件的大小  
            return double.Parse(size.ToString());
        }
        #endregion

        #region 获取指定目录中的文件列表
        /// <summary>  
        /// 获取指定目录中所有文件列表  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>          
        public static string[] GetFileNames(string directoryPath)
        {
            //如果目录不存在,则抛出异常  
            if (!IsExistDirectory(directoryPath))
            {
                throw new FileNotFoundException();
            }

            //获取文件列表  
            return Directory.GetFiles(directoryPath);
        }

        /// <summary>  
        /// 获取指定目录及子目录中所有文件列表  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        /// <param name="searchPattern">模式字符串,"*"代表0或N个字符,"?"代表1个字符。  
        /// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>  
        /// <param name="isSearchChild">是否搜索子目录</param>  
        public static string[] GetFileNames(string directoryPath, string searchPattern, bool isSearchChild)
        {
            //如果目录不存在,则抛出异常  
            if (!IsExistDirectory(directoryPath))
            {
                throw new FileNotFoundException();
            }

            try
            {
                return Directory.GetFiles(directoryPath, searchPattern, isSearchChild ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            }
            catch
            {
                return null;
            }
        }
        #endregion

        #region 获取指定目录中的子目录列表
        /// <summary>  
        /// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>          
        public static string[] GetDirectories(string directoryPath)
        {
            try
            {
                return Directory.GetDirectories(directoryPath);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>  
        /// 获取指定目录及子目录中所有子目录列表  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        /// <param name="searchPattern">模式字符串,"*"代表0或N个字符,"?"代表1个字符。  
        /// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>  
        /// <param name="isSearchChild">是否搜索子目录</param>  
        public static string[] GetDirectories(string directoryPath, string searchPattern, bool isSearchChild)
        {
            try
            {
                return Directory.GetDirectories(directoryPath, searchPattern, isSearchChild ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            }
            catch
            {
                throw null;
            }
        }
        #endregion

        #region 向文本文件写入内容
        /// <summary>  
        /// 向文本文件中写入内容  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        /// <param name="content">写入的内容</param>          
        public static void WriteText(string filePath, string content)
        {
            //向文件写入内容  
            File.WriteAllText(filePath, content);
        }
        #endregion

        #region 向文本文件的尾部追加内容
        /// <summary>  
        /// 向文本文件的尾部追加内容  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        /// <param name="content">写入的内容</param>  
        public static void AppendText(string filePath, string content)
        {
            File.AppendAllText(filePath, content);
        }
        #endregion

        #region 将现有文件的内容复制到新文件中
        /// <summary>  
        /// 将源文件的内容复制到目标文件中  
        /// </summary>  
        /// <param name="sourceFilePath">源文件的绝对路径</param>  
        /// <param name="destFilePath">目标文件的绝对路径</param>  
        public static void Copy(string sourceFilePath, string destFilePath)
        {
            File.Copy(sourceFilePath, destFilePath, true);
        }
        #endregion

        #region 将文件移动到指定目录
        /// <summary>  
        /// 将文件移动到指定目录  
        /// </summary>  
        /// <param name="sourceFilePath">需要移动的源文件的绝对路径</param>  
        /// <param name="descDirectoryPath">移动到的目录的绝对路径</param>  
        public static void Move(string sourceFilePath, string descDirectoryPath)
        {
            //获取源文件的名称  
            string sourceFileName = GetFileName(sourceFilePath);

            if (IsExistDirectory(descDirectoryPath))
            {
                //如果目标中存在同名文件,则删除  
                if (IsExistFile(descDirectoryPath + "\\" + sourceFileName))
                {
                    DeleteFile(descDirectoryPath + "\\" + sourceFileName);
                }
                //将文件移动到指定目录  
                File.Move(sourceFilePath, descDirectoryPath + "\\" + sourceFileName);
            }
        }
        #endregion

        #region 将流读取到缓冲区中
        /// <summary>  
        /// 将流读取到缓冲区中  
        /// </summary>  
        /// <param name="stream">原始流</param>  
        public static byte[] StreamToBytes(Stream stream)
        {
            try
            {
                //创建缓冲区  
                byte[] buffer = new byte[stream.Length];

                //读取流  
                stream.Read(buffer, 0, int.Parse(stream.Length.ToString()));

                //返回流  
                return buffer;
            }
            catch
            {
                return null;
            }
            finally
            {
                //关闭流  
                stream.Close();
            }
        }
        #endregion

        #region 将文件读取到缓冲区中
        /// <summary>  
        /// 将文件读取到缓冲区中  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        public static byte[] FileToBytes(string filePath)
        {
            //获取文件的大小   
            int fileSize = GetFileSize(filePath);

            //创建一个临时缓冲区  
            byte[] buffer = new byte[fileSize];

            //创建一个文件流  
            FileInfo fi = new FileInfo(filePath);
            FileStream fs = fi.Open(FileMode.Open);

            try
            {
                //将文件流读入缓冲区  
                fs.Read(buffer, 0, fileSize);

                return buffer;
            }
            catch
            {
                return null;
            }
            finally
            {
                //关闭文件流  
                fs.Close();
            }
        }
        #endregion

        #region 将文件读取到字符串中
        /// <summary>  
        /// 将文件读取到字符串中  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        public static string FileToString(string filePath)
        {
            return FileToString(filePath, Encoding.Default);
        }
        /// <summary>  
        /// 将文件读取到字符串中  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        /// <param name="encoding">字符编码</param>  
        public static string FileToString(string filePath, Encoding encoding)
        {
            //创建流读取器  
            StreamReader reader = new StreamReader(filePath, encoding);
            try
            {
                //读取流  
                return reader.ReadToEnd();
            }
            catch
            {
                return string.Empty;
            }
            finally
            {
                //关闭流读取器  
                reader.Close();
            }
        }
        #endregion

        #region 从文件的绝对路径中获取文件名( 包含扩展名 )
        /// <summary>  
        /// 从文件的绝对路径中获取文件名( 包含扩展名 )  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static string GetFileName(string filePath)
        {
            //获取文件的名称  
            FileInfo fi = new FileInfo(filePath);
            return fi.Name;
        }
        #endregion

        #region 从文件的绝对路径中获取文件名( 不包含扩展名 )
        /// <summary>  
        /// 从文件的绝对路径中获取文件名( 不包含扩展名 )  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static string GetFileNameNoExtension(string filePath)
        {
            //获取文件的名称  
            FileInfo fi = new FileInfo(filePath);
            return fi.Name.Split('.')[0];
        }
        #endregion

        #region 从文件的绝对路径中获取扩展名
        /// <summary>  
        /// 从文件的绝对路径中获取扩展名  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>          
        public static string GetExtension(string filePath)
        {
            //获取文件的名称  
            FileInfo fi = new FileInfo(filePath);
            return fi.Extension;
        }
        #endregion

        #region 清空指定目录
        /// <summary>  
        /// 清空指定目录下所有文件及子目录,但该目录依然保存.  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        public static void ClearDirectory(string directoryPath)
        {
            if (IsExistDirectory(directoryPath))
            {
                //删除目录中所有的文件  
                string[] fileNames = GetFileNames(directoryPath);
                foreach (string t in fileNames)
                {
                    DeleteFile(t);
                }

                //删除目录中所有的子目录  
                string[] directoryNames = GetDirectories(directoryPath);
                foreach (string t in directoryNames)
                {
                    DeleteDirectory(t);
                }
            }
        }
        #endregion

        #region 清空文件内容
        /// <summary>  
        /// 清空文件内容  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        public static void ClearFile(string filePath)
        {
            //删除文件  
            File.Delete(filePath);

            //重新创建该文件  
            CreateFile(filePath);
        }
        #endregion

        #region 删除指定文件
        /// <summary>  
        /// 删除指定文件  
        /// </summary>  
        /// <param name="filePath">文件的绝对路径</param>  
        public static void DeleteFile(string filePath)
        {
            if (IsExistFile(filePath))
            {
                File.Delete(filePath);
            }
        }
        #endregion

        #region 删除指定目录
        /// <summary>  
        /// 删除指定目录及其所有子目录  
        /// </summary>  
        /// <param name="directoryPath">指定目录的绝对路径</param>  
        public static void DeleteDirectory(string directoryPath)
        {
            if (IsExistDirectory(directoryPath))
            {
                Directory.Delete(directoryPath, true);
            }
        }
        #endregion

        #region 记录错误日志到文件方法
        /// <summary>  
        /// 记录错误日志到文件方法  
        /// </summary>  
        /// <param name="exMessage"></param>  
        /// <param name="exMethod"></param>  
        /// <param name="userID"></param>  
        public static void ErrorLog(string exMessage, string exMethod, int userID)
        {
            try
            {
                string errVir = "/Log/Error/" + DateTime.Now.ToShortDateString() + ".txt";
                string errPath = System.Web.HttpContext.Current.Server.MapPath(errVir);
                File.AppendAllText(errPath,
                                   "{userID:" + userID + ",exMedthod:" + exMethod + ",exMessage:" + exMessage + "}");
            }
            catch
            {

            }
        }
        #endregion

        #region 输出调试日志
        /// <summary>  
        /// 输出调试日志  
        /// </summary>  
        /// <param name="factValue">实际值</param>   
        /// <param name="expectValue">预期值</param>  
        public static void OutDebugLog(object factValue, object expectValue = null)
        {
            string errPath = System.Web.HttpContext.Current.Server.MapPath(string.Format("/Log/Debug/{0}.html", DateTime.Now.ToShortDateString()));
            if (!Equals(expectValue, null))
                File.AppendAllLines(errPath,
                                   new[]{string.Format(  
                                       "【{0}】[{3}] 实际值:<span style='color:blue;'>{1}</span> 预期值: <span style='color:gray;'>{2}</span><br/>",  
                                       DateTime.Now.ToShortTimeString()  
                                       , factValue, expectValue, Equals(expectValue, factValue)  
                                           ? "<span style='color:green;'>成功</span>"  
                                           : "<span style='color:red;'>失败</span>")});
            else
                File.AppendAllLines(errPath, new[]{  
                               string.Format(  
                                   "【{0}】[{3}] 实际值:<span style='color:blue;'>{1}</span> 预期值: <span style='color:gray;'>{2}</span><br/>",  
                                   DateTime.Now.ToShortTimeString()  
                                   , factValue, "空", "<span style='color:green;'>成功</span>")});
        }
        #endregion  
    }
}

JSON

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Data;

namespace YS.Update
{
    /// <summary>
    /// JSON帮助类
    /// </summary>
    public class json
    {
        /// <summary> 
        /// 对象转JSON 
        /// </summary> 
        /// <param name="obj">对象</param> 
        /// <returns>JSON格式的字符串</returns> 
        public static string ObjectToJSON(object obj)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            try
            {
                byte[] b = Encoding.UTF8.GetBytes(jss.Serialize(obj));
                return Encoding.UTF8.GetString(b);
            }
            catch (Exception ex)
            {

                throw new Exception("JSONHelper.ObjectToJSON(): " + ex.Message);
            }
        }

        /// <summary> 
        /// 数据表转键值对集合
        /// 把DataTable转成 List集合, 存每一行 
        /// 集合中放的是键值对字典,存每一列 
        /// </summary> 
        /// <param name="dt">数据表</param> 
        /// <returns>哈希表数组</returns> 
        public static List<Dictionary<string, object>> DataTableToList(DataTable dt)
        {
            List<Dictionary<string, object>> list
                 = new List<Dictionary<string, object>>();

            foreach (DataRow dr in dt.Rows)
            {
                Dictionary<string, object> dic = new Dictionary<string, object>();
                foreach (DataColumn dc in dt.Columns)
                {
                    dic.Add(dc.ColumnName, dr[dc.ColumnName]);
                }
                list.Add(dic);
            }
            return list;
        }

        /// <summary> 
        /// 数据集转键值对数组字典 
        /// </summary> 
        /// <param name="dataSet">数据集</param> 
        /// <returns>键值对数组字典</returns> 
        public static Dictionary<string, List<Dictionary<string, object>>> DataSetToDic(DataSet ds)
        {
            Dictionary<string, List<Dictionary<string, object>>> result = new Dictionary<string, List<Dictionary<string, object>>>();

            foreach (DataTable dt in ds.Tables)
                result.Add(dt.TableName, DataTableToList(dt));

            return result;
        }

        /// <summary> 
        /// 数据表转JSON 
        /// </summary> 
        /// <param name="dataTable">数据表</param> 
        /// <returns>JSON字符串</returns> 
        public static string DataTableToJSON(DataTable dt)
        {
            return ObjectToJSON(DataTableToList(dt));
        }

        /// <summary> 
        /// JSON文本转对象,泛型方法 
        /// </summary> 
        /// <typeparam name="T">类型</typeparam> 
        /// <param name="jsonText">JSON文本</param> 
        /// <returns>指定类型的对象</returns> 
        public static T JSONToObject<T>(string jsonText)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            try
            {
                return jss.Deserialize<T>(jsonText);
            }
            catch (Exception ex)
            {
                throw new Exception("JSONHelper.JSONToObject(): " + ex.Message);
            }
        }

        /// <summary> 
        /// 将JSON文本转换为数据表数据 
        /// </summary> 
        /// <param name="jsonText">JSON文本</param> 
        /// <returns>数据表字典</returns> 
        public static Dictionary<string, List<Dictionary<string, object>>> TablesDataFromJSON(string jsonText)
        {
            return JSONToObject<Dictionary<string, List<Dictionary<string, object>>>>(jsonText);
        }

        /// <summary> 
        /// 将JSON文本转换成数据行 
        /// </summary> 
        /// <param name="jsonText">JSON文本</param> 
        /// <returns>数据行的字典</returns>
        public static Dictionary<string, object> DataRowFromJSON(string jsonText)
        {
            return JSONToObject<Dictionary<string, object>>(jsonText);
        }
    }
}

XML处理类

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Net;
using System.IO;

namespace YS.Update
{
    public class XmlHelper
    {
        #region 增、删、改操作==============================================

        /// <summary>
        /// 追加节点
        /// </summary>
        /// <param name="filePath">XML文档绝对路径</param>
        /// <param name="xPath">范例: @"Skill/First/SkillItem"</param>
        /// <param name="xmlNode">XmlNode节点</param>
        /// <returns></returns>
        public static bool AppendChild(string filePath, string xPath, XmlNode xmlNode)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);
                XmlNode xn = doc.SelectSingleNode(xPath);
                XmlNode n = doc.ImportNode(xmlNode, true);
                xn.AppendChild(n);
                doc.Save(filePath);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 从XML文档中读取节点追加到另一个XML文档中
        /// </summary>
        /// <param name="filePath">需要读取的XML文档绝对路径</param>
        /// <param name="xPath">范例: @"Skill/First/SkillItem"</param>
        /// <param name="toFilePath">被追加节点的XML文档绝对路径</param>
        /// <param name="toXPath">范例: @"Skill/First/SkillItem"</param>
        /// <returns></returns>
        public static bool AppendChild(string filePath, string xPath, string toFilePath, string toXPath)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(toFilePath);
                XmlNode xn = doc.SelectSingleNode(toXPath);

                XmlNodeList xnList = ReadNodes(filePath, xPath);
                if (xnList != null)
                {
                    foreach (XmlElement xe in xnList)
                    {
                        XmlNode n = doc.ImportNode(xe, true);
                        xn.AppendChild(n);
                    }
                    doc.Save(toFilePath);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 修改节点的InnerText的值
        /// </summary>
        /// <param name="filePath">XML文件绝对路径</param>
        /// <param name="xPath">范例: @"Skill/First/SkillItem"</param>
        /// <param name="value">节点的值</param>
        /// <returns></returns>
        public static bool UpdateNodeInnerText(string filePath, string xPath, string value)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);
                XmlNode xn = doc.SelectSingleNode(xPath);
                XmlElement xe = (XmlElement)xn;
                xe.InnerText = value;
                doc.Save(filePath);
            }
            catch
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 读取XML文档
        /// </summary>
        /// <param name="filePath">XML文件绝对路径</param>
        /// <returns></returns>
        public static XmlDocument LoadXmlDoc(string filePath)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);
                return doc;
            }
            catch
            {
                return null;
            }
        }
        #endregion 增、删、改操作

        #region 扩展方法===================================================
        /// <summary>
        /// 读取XML的所有子节点
        /// </summary>
        /// <param name="filePath">XML文件绝对路径</param>
        /// <param name="xPath">范例: @"Skill/First/SkillItem"</param>
        /// <returns></returns>
        public static XmlNodeList ReadNodes(string filePath, string xPath)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);
                XmlNode xn = doc.SelectSingleNode(xPath);
                XmlNodeList xnList = xn.ChildNodes;  //得到该节点的子节点
                return xnList;
            }
            catch
            {
                return null;
            }
        }

        ///<summary>
        /// 加载远程XML文档
        ///</summary>
        ///<param name="URL"></param>
        ///<returns></returns>
        public static XmlDocument loadxml(string URL)
        {
            //使用rssURL的值建立了一个WebRequest项
            WebRequest myRequest = WebRequest.Create(URL);
            //WebRequest请求的响应将会被放到一个WebResponse对象myResponse里,然后这个WebResponse对象被用来建立一个流来取出XML的值
            try
            {
                WebResponse myResponse = myRequest.GetResponse();
                Stream stream = myResponse.GetResponseStream();
                //使用一个XmlDocument对象rssDoc来存储流中的XML内容。XmlDocument对象用来调入XML的内容
                XmlDocument doc = new XmlDocument();
                doc.Load(stream);
                return doc;
            }
            catch
            {
                return null;
            }
        }
        #endregion 扩展方法
    }
}

update.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Threading.Tasks;

namespace YS.Update
{
    /// <summary>
    /// 需要如下方法
    /// 1.获取文件MD5
    /// 2.获取远程文件
    /// 3.对比本地文件MD5
    /// 4.替换本地文件
    /// 5.文件缓存处理
    /// 6.本地文件自动备份
    /// 7.更新文件列表
    /// 8.数据库更新文件缓存
    /// </summary>
    public class update
    {
        public string url = null;
        public string cmd = null;
        public bool flag = false;
        public static string GetMD5Hash(string fileName)
        {
            try
            {
                FileStream file = new FileStream(fileName, FileMode.Open);
                System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(file);
                file.Close();

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("GetMD5Hash() fail,error:" + ex.Message);
            }
        }
        /// <summary>
        /// 读取配置文件
        /// </summary>
        public update()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "xmlconfig/update.xml";

            try
            {
                if (path != null)
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(path);
                    url = xmlDoc.SelectSingleNode("/update/url").InnerText;

                }
            }
            catch (Exception ex)
            {
                throw new Exception("找不到autoUpdate.xml文件" + ex.Message);

            }
        }
        //获取服务器的版本
        public Version GetServerVersion()
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(url);
            return new Version(xmlDoc.SelectSingleNode("/update/version").InnerText);
        }
        //获取客户端版本
        public string GetClientVersion()
        {
            url = AppDomain.CurrentDomain.BaseDirectory + "userVersion.xml";
            XmlDocument xmlUser = new XmlDocument();
            xmlUser.Load(url);
            XmlElement root = xmlUser.DocumentElement;
            XmlNode updateNode = root.SelectSingleNode("version");
            string version = updateNode.Attributes["value"].Value;
            return version;

        }
        //为了进行版本比较,进行转换为整数比较
        public int ConvertVersion(string value)
        {
            int w, z, x, y, temp;
            w = int.Parse(value.Substring(0, 1));
            z = int.Parse(value.Substring(2, 1));
            x = int.Parse(value.Substring(4, 1));
            y = int.Parse(value.Substring(6, 1));
            temp = w * 1000 + z * 100 + x * 10 + y;
            return temp;
        }
        //更新客户版本号为服务器的版本号
        public string UpdateVersion(string serVersion)
        {
            url = AppDomain.CurrentDomain.BaseDirectory + "userVersion.xml";
            XmlDocument xmlUser = new XmlDataDocument();
            xmlUser.Load(url);
            XmlElement root = xmlUser.DocumentElement;
            XmlNode updateNode = root.SelectSingleNode("version");
            string strVer = updateNode.Attributes["value"].Value;
            updateNode.Attributes["value"].Value = serVersion;
            xmlUser.Save(url);
            return serVersion;
        }
        /// <summary>
        ///从服务器文件update.xml中获取要下载的文件列表
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public string[] GetFileList(string url)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(url);
            XmlElement root = xmlDoc.DocumentElement;
            XmlNode updateNode = root.SelectSingleNode("filelist");
            string soucePath = updateNode.Attributes["sourcepath"].Value;

            string fileName = null;
            string fileList = null;
            //取出服务器里update.xml里更新的file文件
            XmlNodeList fileNode = updateNode.SelectNodes("file");
            if (fileNode != null)
            {
                foreach (XmlNode i in fileNode)
                {
                    foreach (XmlNode j in i)
                    {
                        if (i.Attributes["filesname"].Value != "")
                            fileName = soucePath + i.Attributes["filesname"].Value + "/" + j.Attributes["name"].Value +
                                "$" + i.Attributes["filesname"].Value + "/" + j.Attributes["name"].Value;
                        else
                            fileName = soucePath + j.Attributes["name"].Value +
                                "$" + j.Attributes["name"].Value;

                        fileName += ",";
                        fileList += fileName;
                    }
                }

                string[] splitFile = fileList.Split(',');
                flag = true;
                return splitFile;
            }
            return null;
        }
      
    }

    [Serializable]
    public partial class filemodel
    {
        public filemodel()
        { }
        private string _filename;
        public string filename
        {
            get { return _filename; }
            set { _filename = value; }
        }
    }

    [Serializable]
    public partial class sqlmodel
    {
        public sqlmodel()
        { }
        private string _tablename;
        private string _sqlid;
        private string _sql;
        public string tablename
        {
            get { return _tablename; }
            set { _tablename = value; }
        }
        public string sqlid
        {
            get { return _sqlid; }
            set { _sqlid = value; }
        }
        public string sql
        {
            get { return _sql; }
            set { _sql = value; }
        }
    }
}

 

update 后端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Net;
using System.IO;
using System.Web;
using System.Security.Cryptography;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Data.Common;
using System.Text.RegularExpressions;

namespace YS.Update.page
{
    public partial class goupdate : System.Web.UI.Page
    {
        protected string updateurl = "";
        XmlDocument xmldoc = null;
        protected static int f_num = 0;
        protected static int s_num = 0;
        protected static int c_num = 0;

        protected static List<filemodel> flist = new List<filemodel>();
        protected static List<sqlmodel> qlist = new List<sqlmodel>();
       
        protected void Page_Load(object sender, EventArgs e)
        {
            xmldoc = XmlHelper.LoadXmlDoc(Server.MapPath(@"~/xmlconfig/versioncach.xml"));
            if (!IsPostBack)
            {               
                XmlNode url = xmldoc.SelectSingleNode(@"root/url");
                if (url == null || url.InnerText == "")
                {
                    Response.Write("参数丢失,请联系管理员");
                    Response.End();
                }
                updateurl = url.InnerText;
            }
            if (Request.QueryString["action"] == "checkupdate")
            {
                checkupdate();
                return;
            }
            if (Request.QueryString["action"] == "resfile")
            {
                resfile();
                return;
            }
            if (Request.QueryString["action"] == "process")
            {
                process();
                return;
            }
            
        }
        /// <summary>
        /// 写cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="strValue">值</param>
        public static void WriteCookie(string strName, string strValue)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[strName];
            if (cookie == null)
            {
                cookie = new HttpCookie(strName);
            }
            cookie.Value = UrlEncode(strValue);
            HttpContext.Current.Response.AppendCookie(cookie);
        }
        /// <summary>
        /// 读cookie值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>cookie值</returns>
        public static string GetCookie(string strName)
        {
            if (HttpContext.Current.Request.Cookies != null && HttpContext.Current.Request.Cookies[strName] != null)
                return UrlDecode(HttpContext.Current.Request.Cookies[strName].Value.ToString());
            return "";
        }
        /// <summary>
        /// URL字符编码
        /// </summary>
        public static string UrlEncode(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            str = str.Replace("'", "");
            return HttpContext.Current.Server.UrlEncode(str);
        }

        /// <summary>
        /// URL字符解码
        /// </summary>
        public static string UrlDecode(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            return HttpContext.Current.Server.UrlDecode(str);
        }
        private void checkupdate()
        {
            f_num = 0;
            s_num = 0;
            c_num = 0;
            flist.Clear();
            qlist.Clear();
            WriteCookie("c_num","0");
            XmlDocument newfile = XmlHelper.loadxml(updateurl+"xmlconfig/update.xml");
            if (newfile == null)
            {
                Response.Write("{\"status\": 0, \"msg\": \"\"}");
            }
            XmlNode xn = newfile.SelectSingleNode(@"root/checkfiles");
            XmlNodeList xnList = xn.ChildNodes;  //得到该节点的子节点
            XmlNode ckfnote = xmldoc.SelectSingleNode(@"root/checkfiles");
            ckfnote.RemoveAll();//移除旧数据
            foreach (XmlNode item in xnList)
            {
                string url=item.Attributes["name"].Value;
                if (!FileHelper.IsExistFile(Server.MapPath("/" + url)))
                {
                    XmlElement newnote = xmldoc.CreateElement("file");
                    newnote.InnerText = item.Attributes["name"].Value;
                    ckfnote.AppendChild(newnote);
                    filemodel fm = new filemodel();
                    fm.filename = item.Attributes["name"].Value;
                    flist.Add(fm);
                    f_num++;
                }
                else
                {
                    string md5 = update.GetMD5Hash(Server.MapPath("/" + url));
                    if (md5 != item.Attributes["md5"].Value)
                    {
                        XmlElement newnote = xmldoc.CreateElement("file");
                        newnote.InnerText = item.Attributes["name"].Value;
                        ckfnote.AppendChild(newnote);
                        filemodel fm = new filemodel();
                        fm.filename = item.Attributes["name"].Value;
                        flist.Add(fm);
                        f_num++;
                    }
                }
            }
            XmlNode sqlnote = xmldoc.SelectSingleNode(@"root/sqlupdate");
            XmlNode xn1 = newfile.SelectSingleNode(@"root/sqlupdate");
            XmlNodeList xnList1 = xn1.ChildNodes;  //得到该节点的子节点

            foreach (XmlNode item in xnList1)
            {
                if (sqlnote.SelectSingleNode("//sql[@sqlid='" + item.Attributes["sqlid"].Value + "']")==null)
                {
                    XmlNode n = xmldoc.ImportNode(item, true);
                    sqlnote.AppendChild(n);
                }
            }
            foreach (XmlNode item in sqlnote)
            {
                if (item.Attributes["isrun"].Value.ToString() == "0")
                {
                    sqlmodel sm = new sqlmodel();
                    sm.tablename = item.Attributes["tablename"].Value;
                    sm.sqlid = item.Attributes["sqlid"].Value;
                    qlist.Add(sm);
                    s_num++;
                }
            }
            ///下载文件测试
            //DownFileFromServ(updateurl + "admin/update/update.aspx?action=resfile&file=/bin/DTcms.Web.dll", AppDomain.CurrentDomain.BaseDirectory + "/test/DTcms.Web.dll");
            ///
            xmldoc.Save(Server.MapPath(@"~/xmlconfig/versioncach.xml"));
            Response.Write("{\"status\": 1, \"files\": " + json.ObjectToJSON(flist) + ",\"sqls\":"+json.ObjectToJSON(qlist)+"}");
            Response.End();
        }
        private void getflist()
        {
            flist.Clear();
            qlist.Clear();
            XmlDocument doc = XmlHelper.LoadXmlDoc(Server.MapPath(@"~/xmlconfig/versioncach.xml"));
            XmlNode sqlnote = xmldoc.SelectSingleNode(@"root/sqlupdate");
            XmlNodeList xnList1 = sqlnote.ChildNodes;
            foreach (XmlNode item in sqlnote)
            {
                if (item.Attributes["isrun"].Value.ToString() == "0")
                {
                    sqlmodel sm = new sqlmodel();
                    sm.tablename = item.Attributes["tablename"].Value;
                    sm.sqlid = item.Attributes["sqlid"].Value;
                    sm.sql = item.InnerText;
                    qlist.Add(sm);
                }
            }
            XmlNode ckfnote = doc.SelectSingleNode(@"root/checkfiles");
            XmlNodeList xnList = ckfnote.ChildNodes;
            foreach (XmlNode item in xnList)
            {

                    filemodel fm = new filemodel();
                    fm.filename = item.InnerText;
                    flist.Add(fm);
                
            }

        }

        private void process()
        {
            XmlDocument doc = XmlHelper.LoadXmlDoc(Server.MapPath(@"~/xmlconfig/versioncach.xml"));
            if (doc == null)
            {
                Response.End();
                return;
            }
            string type = Request.Form["type"];
            if (type == "file")
            {
                getflist();
                c_num =Int32.Parse(GetCookie("c_num"));
                if (flist.Count == c_num)
                {
                    Response.Write("{\"status\":0,\"result\":{\"total\": " + flist.Count + ", \"success\": " + c_num + ",\"action\":\"file\"}}");
                    WriteCookie("c_num", "0");
                    c_num = 0;
                    Response.End();
                    
                    return;
                }
               
                if (DownFileFromServ(updateurl + "admin/update/update.aspx?action=resfile&file=/" + flist[c_num].filename, AppDomain.CurrentDomain.BaseDirectory + "/" + flist[c_num].filename))
                {
                    c_num++;
                    WriteCookie("c_num", c_num.ToString());
                    Response.Write("{\"status\":1,\"result\":{\"total\": " + flist.Count + ", \"success\": " + c_num + ",\"action\":\"file\"}}");
                    Response.End();

                    return;
                }
                else
                {
                    c_num++;
                    WriteCookie("c_num", c_num.ToString());
                    Response.Write("{\"status\":2,\"result\":{\"total\": " + flist.Count + ", \"emsg\": \"更新文件失败,请联系管理员!\",\"action\":\"file\"}}");
                    Response.End();
                    return;
                }
            }
            if (type == "database")
            {
                getflist();
                c_num = Int32.Parse(GetCookie("c_num"));
                if (qlist.Count == c_num)
                {
                    Response.Write("{\"status\":0,\"result\":{\"total\": " + qlist.Count + ", \"success\": " + c_num + ",\"action\":\"database\"}}");
                    WriteCookie("c_num", "0");
                    c_num = 0;
                    Response.End();

                    return;
                }
                if (ExecuteSqlWithGo(qlist[c_num].sql))
                {

                    XmlNode sqlnote = doc.SelectSingleNode(@"root/sqlupdate");
                    XmlElement note1 = (XmlElement)sqlnote.SelectSingleNode("//sql[@sqlid='" + qlist[c_num].sqlid + "']");
                    note1.SetAttribute("isrun", "1");
                    doc.Save(Server.MapPath(@"~/xmlconfig/versioncach.xml"));
                    c_num++;
                    WriteCookie("c_num", c_num.ToString());

                    Response.Write("{\"status\":1,\"result\":{\"total\": " + qlist.Count + ", \"success\": " + c_num + ",\"action\":\"database\"}}");
                    Response.End();

                    return;
                }
                else
                {
                    c_num++;
                    WriteCookie("c_num", c_num.ToString());
                    Response.Write("{\"status\":2,\"result\":{\"total\": " + qlist.Count + ", \"emsg\": \"更新数据库失败,请联系管理员!\",\"action\":\"database\"}}");
                    Response.End();
                    return;
                }
            }
        }
        public static bool ExecuteSqlWithGo(String sql)
        {
            int effectedRows = 0;
            string connectionString =  ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;
                try
                {
                    //注: 此处以 换行_后面带0到多个空格_再后面是go 来分割字符串
                    String[] sqlArr = Regex.Split(sql.Trim(), "\r\n\\s*go", RegexOptions.IgnoreCase);
                    foreach (string strsql in sqlArr)
                    {
                        if (strsql.Trim().Length > 1 && strsql.Trim() != "\r\n")
                        {
                            cmd.CommandText = strsql;
                            effectedRows = cmd.ExecuteNonQuery();
                        }
                    }
                    return true;
                }
                catch (System.Data.SqlClient.SqlException E)
                {
                    return false;
                }
                finally
                {
                    conn.Close();
                }
            }
        }
        private void resfile()
        {
            string fileurl = Request.QueryString["file"];
            if (fileurl == "")
            {
                return;
            }
            Response.WriteFile(Server.MapPath(fileurl));
            Response.End();
        }
        public bool DownFileFromServ(string url, string fileName)
        {
            bool downsucess = false;
            try
            {
                string fileExtraName = url.Split(char.Parse("."))[0];                              //文件名
                string fileAfterName = System.IO.Path.GetExtension(url);                //文件的扩展名

                HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
                myReq.KeepAlive = true;
                HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();

                downsucess = this.CopyFileAndDirectory(myRes, fileName);

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            return downsucess;
        }

        //返回复制文件或创建目录是否成功
        public bool CopyFileAndDirectory(WebResponse myResp, string fileName)
        {
            bool flag = true;
            byte[] buffer = new byte[0x400];
            try
            {
                int num;
                //若本身已有该目录则删除
                if (System.IO.File.Exists(fileName))
                {
                    System.IO.File.Delete(fileName);
                }
                //创建目录更新到Updat目录下
                string directoryName = Path.GetDirectoryName(fileName);
                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }

                //指定文件fileName不存在时创建它
                Stream streamRead = System.IO.File.Open(fileName, FileMode.Create);

                Stream responseStream = myResp.GetResponseStream();

                do
                {
                    //从当前读取的字节流数,复制
                    num = responseStream.Read(buffer, 0, buffer.Length);
                    if (num > 0)
                    {
                        streamRead.Write(buffer, 0, num);
                    }
                }
                while (num > 0);
                streamRead.Close();
                responseStream.Close();
            }
            catch
            {
                flag = false;
            }

            return flag;

        }
    }
}

update页面前端

<%@ Page Language="C#" AutoEventWireup="true"  Inherits="YS.Update.page.goupdate" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
	<link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
	<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
	<script src="/admin/js/util.js"></script>
    <link href="../skin/common.css" rel="stylesheet" />
    <style>
        .upgrade-info{width:80%; margin:auto;}
    </style>
</head>
<body>
    <form id="form1" runat="server" class="form we7-form">
     <div style="text-align:center; padding-top:100px;" id="stp1">
         <div id="tips"></div>
    </div>

		<div class="upgrade-info we7-padding-bottom" hidden="true">
			<div class="panel we7-panel">
				<div class="panel-heading we7-padding">
					<span class="col-sm-2 we7-padding-none color-gray">发现新版本可以更新</span>
				</div>
				<div class="panel-body we7-padding">
					<div class="form-group">
						<label for="" class="control-label color-gray col-sm-2">需要更新文件</label>
						<div class="form-controls col-sm-7 form-control-static"><span id="file_num"></span> 个</div>
						<span class="color-default col-sm-3 text-right"><a href="#upgrade-file" data-toggle="modal" >查看</a></span>
					</div>
					<div class="form-group">
						<label for="" class="control-label color-gray col-sm-2">需要更新数据库</label>
						<div class="form-controls col-sm-7 form-control-static"><span id="sql_num"></span> 项</div>
						<span class="color-default col-sm-3 text-right"><a href="#upgrade-databases" data-toggle="modal" >查看</a></span>
					</div>
					<div class="form-group  we7-padding-none">
						
					</div>
				</div>
			</div>
			<div class="text-center">
				<input type="button" name="" id="forward" value="一键更新" class="btn btn-danger" />
				<input type="button" name="" id="process" value="正在更新,请不要关闭浏览器" class="btn btn-danger" style="display:none;" />
                <div id="emsg" style="color:red;"></div>
			</div>
		</div>



<div class="modal fade" id="upgrade-file" tabindex="-1" role="dialog" aria-hidden="true">
	<div class="modal-dialog we7-modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">
					<span aria-hidden="true">&times;</span>
					<span class="sr-only">Close</span>
				</button>
				<h4 class="modal-title">更新文件</h4>
			</div>
			<div class="modal-body color-dark" id="file_list">


							</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-primary"  data-dismiss="modal">确定</button>
			</div>
		</div>
	</div>
</div>


<div class="modal fade" id="upgrade-databases" tabindex="-1" role="dialog" aria-hidden="true">
	<div class="modal-dialog we7-modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">
					<span aria-hidden="true">&times;</span>
					<span class="sr-only">Close</span>
				</button>
				<h4 class="modal-title">更新数据库</h4>
			</div>
			<div class="modal-body color-dark" id="sql_list">

							</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-primary"  data-dismiss="modal">确定</button>
			</div>
		</div>
	</div>
</div


    </form>
</body>
</html>
<script type="text/javascript">
    $(function () {
        getupdate();
    })
    $('#forward').click(function () {
        var a = $("#agreement_0").is(':checked');
        var b = $("#agreement_1").is(':checked');
        if (confirm('更新将直接覆盖本地文件, 请注意备份文件和数据. \n\n**另注意** 更新过程中不要关闭此浏览器窗口.')) {
            // location.href = './index.php?c=cloud&a=process&';
            $("#forward").hide();
            $("#process").show();
            process("file");
        }
    });
    function process(action) {
        $.ajax({
            url: "/updatecach.aspx?action=process",
            data: { type: action },
            type: 'post',
            dataType: 'json',
            success: function (ret) {
                var status = ret.status;
                var result = ret.result;
                var act = result.action;
                console.log(ret);
                if (act == 'database') {

                    if (status == 1) {
                        $('#process').val("已更新 " + result.success + " 条数据库结构变动 / 共 " + result.total + " 条");
                        process('database');
                    }
                    else if (status == 2) {
                        $("#emsg").append("<div>" + result.emsg + "</div>");
                        process('database');
                    }
                    else {
                        $('#process').val("已成功更新 " + result.total + " 条数据库结构变动");
                        $('#process').val('更新成功');
                        alert("更新成功,如有错误信息请联系管理员解决");
                        location.reload();
                    }


                } else if (act == 'file') {

                    if (status == 1) {
                        $('#process').val("已更新 " + result.success + " 个文件 / 共 " + result.total + " 个文件");
                        process('file');
                    } else if (status == 2) {
                        $("#emsg").append("<div>" + result.emsg + "</div>");
                        process('file');
                    } else {
                        $('#process').val("已成功更新 " + result.total + " 个文件");
                        process('database');
                    }

                } 
            }
        });
    }
    function getupdate() {
        $("#tips").html("正在检测新版本,请耐心等待");
        $.ajax({
        url: "/admin/update/update.aspx?action=checkupdate",
        type: 'post',
        dataType: 'json',
        success: function (ret) {            
            console.log(ret);
            if (ret.status == 0)
            {
                util.message("检测更新失败,请联系管理员", '', 'error');
            }
            if (ret.status == 1) {

                var html = "";

                if (ret.files.length <= 0 && ret.sqls.length <= 0) {

                    html = "恭喜您,您现在是最新版本!";
                    $("#tips").html(html);

                } else {//更新显示逻辑
                    $("#stp1").hide();
                    $("#file_num").html(ret.files.length);
                    $("#sql_num").html(ret.sqls.length);
                    $(".upgrade-info").show();
                    for (var i = 0; i < ret.files.length; i++)
                    {
                        html += "<div>" + ret.files [i].filename+ "</div>";
                    }
                    $("#file_list").html(html);
                    html = "";
                    for (var i = 0; i < ret.sqls.length; i++) {
                        html += "<div>" + ret.sqls[i].tablename + "</div>";
                    }
                    $("#sql_list").html(html);
                }
            }
        }
    })
    }
</script>

makeupdate 页面后端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace YS.Update.page
{
    public partial class makeupdate : System.Web.UI.Page
    {
        protected global::System.Web.UI.HtmlControls.HtmlGenericControl msgtip;
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            msgtip.InnerHtml = "正在处理数据,请稍后...";
            string baseurl = System.AppDomain.CurrentDomain.BaseDirectory;
            XmlDocument xmldoc = XmlHelper.LoadXmlDoc(Server.MapPath(@"~/xmlconfig/update.xml"));
            XmlNode ckfnote = xmldoc.SelectSingleNode(@"root/checkfiles");
            ckfnote.RemoveAll();//移除旧数据
            XmlNodeList folderlist = XmlHelper.ReadNodes(Server.MapPath(@"~/xmlconfig/update.xml"), @"root/folders");//文件夹列表
            if (folderlist != null)
            {
                foreach (XmlNode i in folderlist)
                {
                    if (FileHelper.IsExistDirectory(Server.MapPath(i.InnerText)))
                    {
                        string[] filelist = FileHelper.GetFileNames(Server.MapPath(i.InnerText), "*", true);

                        List<string> list = filelist.Where(s => s.ToLower().EndsWith(".aspx") || s.ToLower().EndsWith(".css") || s.ToLower().EndsWith(".js") || s.ToLower().EndsWith(".html") || s.ToLower().EndsWith(".xml") || s.ToLower().EndsWith(".ashx") || s.ToLower().EndsWith(".dll")).ToList();
                       
                        foreach (string item in list)
                        {
                            string md5 = update.GetMD5Hash(item);
                            string fileurl = item.Replace(baseurl, "");
                            XmlElement newnote = xmldoc.CreateElement("file");
                            newnote.SetAttribute("name",fileurl);
                            newnote.SetAttribute("md5",md5);
                            ckfnote.AppendChild(newnote);
                         }

                    }
                }
            }
           
            XmlNodeList files = XmlHelper.ReadNodes(Server.MapPath(@"~/xmlconfig/update.xml"), @"root/files");//文件列表
            if (files != null)
            {
                foreach (XmlNode i in files)
                {
                    if (FileHelper.IsExistFile(Server.MapPath(i.InnerText)))
                    {
                        string md5 = update.GetMD5Hash(Server.MapPath(i.InnerText));
                        string fileurl = Server.MapPath(i.InnerText).Replace(baseurl, "");
                        XmlElement newnote = xmldoc.CreateElement("file");
                        newnote.SetAttribute("name", fileurl);
                        newnote.SetAttribute("md5", md5);
                        ckfnote.AppendChild(newnote);
                    }
                }
            }

            xmldoc.Save(Server.MapPath(@"~/xmlconfig/update.xml"));
            msgtip.InnerHtml = "更新版本配置文件成功,如有数据库更新请手动修改配置文件"; 
            
        }
    }
}

makeupdate页面前端

<%@ Page Language="C#" AutoEventWireup="true"  Inherits="YS.Update.page.makeupdate" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
    <style>
        .btn{margin:auto; width:250px; height:50px;}
    </style>
<body>
    <form id="form1" runat="server">
    <div style="text-align:center; padding-top:100px;">
    <asp:Button ID="btnSubmit" runat="server" Text="更新版本服务端数据" CssClass="btn" onclick="btnSubmit_Click" />
        <p id="msgtip" runat="server"></p>
    </div>
    </form>
</body>
</html>

versioncach.xml

<?xml version="1.0" encoding="utf-8"?>
<root>
  <url>http://127.0.0.1/</url>
  <sqlupdate>
  </sqlupdate>
  <checkfiles>    
    <file>aspx\wxapp\repassword.aspx</file>
  </checkfiles>
</root>

update.xml 用于存储校验配置及文件特征

<?xml version="1.0" encoding="utf-8"?>
<root>
  <version>1.0.1.9</version>
  <url>http://test.yunbaokai.com/</url>
  <folders>
    <folder>/admin/</folder>
    <folder>/api/</folder>
    <folder>/bin/</folder>
    <folder>/css/</folder>
    <folder>/dialog/</folder>
    <folder>/editor/</folder>
    <folder>/scripts/</folder>
    <folder>/tools/</folder>
    <folder>/aspx/</folder>
    <folder>/templates/</folder>
  </folders>
  <files>
    <file>/get_yhq.aspx</file>
    <file>/postgo.aspx</file>
  </files>
  <sqlupdate>
    <sql tablename="test" sqlid="1" isrun="0"><![CDATA[ 
      if not exists (select * from sysobjects where id = object_id('mytab') and OBJECTPROPERTY(id, 'IsUserTable') = 1)
      create table  mytab
      (
      id int,
      age int ,
      name varchar(max),
      primary key (id,age)
      )
      ]]></sql>   
  </sqlupdate>
  <checkfiles>
    <file name="admin\center.aspx" md5="1e1742090e34d9b7baba5a8930e6c641" />
    <file name="admin\ie6update.html" md5="48f37c02cd5ad9e04b2ea815c0041723" />
    <file name="admin\index.aspx" md5="546dd4a4ae928308923c598ea75b6f9d" />
    <file name="admin\login.aspx" md5="cceaf8ce293d3fb0281ed462be53bff9" />
    <file name="admin\logout.aspx" md5="0b66270bec9d59777bdf56895d690981" />
    <file name="admin\mlogin.aspx" md5="94ba2a49786124d558c9e0497e30fc61" />
    <file name="admin\article\article_dan.aspx" md5="84f6959702ceda4f7e0eaaa1de1e0c46" />

  </checkfiles>
</root>

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值