C#之tcp自动更新程序

Posted 天宝爱人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#之tcp自动更新程序相关的知识,希望对你有一定的参考价值。

.NETTCP自动更新程序有如下几步骤:

第一步:服务端开启监听

ServiceHost host;
        private void button1_Click(object sender, EventArgs e)
        {
            host = new ServiceHost(typeof(WCFService.Service));
            host.Open();
            if (host.State == CommunicationState.Opened)
            {
                this.button1.Enabled = false;
                this.button2.Enabled = true;
            }
            this.label1.Text = host.State.ToString();
        }
View Code

第二步:客户端创建服务连接,不多说,大家应该都会

第三步:客户端选择更新文件(包括了一个Read_File)

#region 选择文件按钮
        private void btn_SelectFiles_Click(object sender, EventArgs e)
        {
            dt_updatefile.Clear();
            OpenFileDialog File_XuanZe = new OpenFileDialog();
            File_XuanZe.Multiselect = true;//允许同时选择多个文件 
            File_XuanZe.Filter = "Dll files(*.dll)|*.dll|Txt files(*.txt)|*.txt|Access files(*.mdb)|*.mdb|All files(*.*)|*.*";
            if (DialogResult.OK == File_XuanZe.ShowDialog())
            {
                for (int i = 0; i < File_XuanZe.FileNames.Length; i++)
                {
                    byte[] buff = Read_File(File_XuanZe.FileNames[i]);
                    //第三列为版本号 应该设置一个textbox为版本号
                    //第四列为存放路径 例如图片就在图片文件夹,可执行文件就在根目录下
                    dt_updatefile.Rows.Add(i + 1, File_XuanZe.SafeFileNames[i], txt_version.Text, @"\\图片\\", buff);
                }
            }
            dataGridView1.DataSource = dt_updatefile;
        }
        #endregion

        #region 将文件转换成byte[] Read_File
        public byte[] Read_File(string str_path)
        {
            byte[] arrFile = null; //先定义一个byte数组
            using (FileStream fs = new FileStream(str_path, FileMode.Open, FileAccess.Read)) //path是文件的路径
            {
                arrFile = new byte[fs.Length];//定义这个byte[]数组的长度 为文件的length
                fs.Read(arrFile, 0, arrFile.Length);//把fs文件读入到arrFile数组中,0是指偏移量,从0开始读,arrFile.length是指需要读的长度,也就是整个文件的长度
                return arrFile;
            }
        }
        #endregion
View Code

第四步:上传更新文件,采用数据序列化并压缩后上传

#region 上传文件按钮
        private void btn_UpdateFile_Click(object sender, EventArgs e)
        {
            DataSet ds = new DataSet();
            if(dt_updatefile.DataSet != null)
            {
                dt_updatefile.DataSet.Tables.Remove(dt_updatefile);
            }
            ds.Tables.Add(dt_updatefile);
            client.Update_System(data_Serializer.GetDataSetSurrogateZipBytes(ds));
            Load_OldFiles();
            dt_updatefile.Clear();
        }
        #endregion
View Code

第五步:服务端接受数据并写文件,修改XML中版本信息

#region 接受客户端发来的更新数据包Update_System
        public void Update_System(byte[] byte_files)
        {
            DataSet ds = data_Serializer.GetZipBytesSurrogateDataSet(byte_files);
            //解压成了dataset 循环存放文件,并修改Version_Config.xml中对应的值
            DataTable dt = ds.Tables[0];
            foreach(DataRow dr in dt.Rows)
            {
                string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\\" + dr["Col_Version"] +dr["Col_File_Path"];
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (File.Exists(path + dr["Col_File_Name"].ToString()))
                {
                    //存在文件
                    File.Delete(path + dr["Col_File_Name"].ToString());
                }
                #region 回写文件 没有排除掉重复文件
                //判断此文件是否存在,存在则修改为原文件名+年月日时分秒,不存在就写文件
                byte[] buffer = (byte[])dr["Col_File_Size"];
                FileStream fs = new FileStream(path + dr["Col_File_Name"].ToString(), FileMode.Create, FileAccess.Write);
                Stream stream = new MemoryStream((byte[])dr["Col_File_Size"]);
                int count = 0;
                while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fs.Write(buffer, 0, count);
                }
                //清空缓冲区
                fs.Flush();
                //关闭流
                fs.Close();
                #endregion
                //写文件完成了,现在就是修改xml中的值了
                configXml.Update_Xml(dr["Col_File_Name"].ToString(), dr["Col_Version"].ToString(), dr["Col_File_Path"].ToString());
            }
        }
        #endregion
View Code

第六步:客户端检测版本号,更新程序

#region 下载文件btn_DownFiles_Click
        private void btn_DownFiles_Click(object sender, EventArgs e)
        {
            System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
            xDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config");
            System.Xml.XmlNode xNode;
            System.Xml.XmlElement xElem1;
            xNode = xDoc.SelectSingleNode("//appSettings");
            xElem1 = (System.Xml.XmlElement)xNode.SelectSingleNode("//add[@key=\'version\']");

            DataSet ds = data_Serializer.GetZipBytesSurrogateDataSet(client.DownFiles(ConfigurationManager.AppSettings["version"]));
            DataTable dt_file = ds.Tables[0];
            //linq
            Double maxSV = Creat_Version();
            foreach (DataRow dr in dt_file.Rows)
            {
                string path = System.AppDomain.CurrentDomain.BaseDirectory + dr["Col_File_Path"];
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                if (File.Exists(path + dr["Col_File_Name"].ToString()))
                {
                    //存在文件
                    File.Delete(path + dr["Col_File_Name"].ToString());
                }
                #region 回写文件 没有排除掉重复文件
                //判断此文件是否存在,存在则修改为原文件名+年月日时分秒,不存在就写文件
                byte[] buffer = (byte[])dr["Col_File_Size"];
                FileStream fs = new FileStream(path + dr["Col_File_Name"].ToString(), FileMode.Create, FileAccess.Write);
                Stream stream = new MemoryStream((byte[])dr["Col_File_Size"]);
                int count = 0;
                while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fs.Write(buffer, 0, count);
                }
                //清空缓冲区
                fs.Flush();
                //关闭流
                fs.Close();
                #endregion
            }
            //写文件完成了,现在就是修改xml中的值了
            xElem1.SetAttribute("value", maxSV.ToString());
            xDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config");
        }
        #endregion
View Code

大致就是以上步骤。具体中的类等信息没有在代码中贴出,可以下载源代码进行研究。

缺陷:

第一:客户端调用没有判断服务是否开启

第二:文件存放路径还没写完整

第三:暂时自己大脑没想到。

源码下载https://yunpan.cn/cSbKnajf63ptA  访问密码 42ac

 

以上是关于C#之tcp自动更新程序的主要内容,如果未能解决你的问题,请参考以下文章

如何为 XSLT 代码片段配置 CruiseControl 的 C# 版本?

C#程序员经常用到的10个实用代码片段 - 操作系统

C#程序员经常用到的10个实用代码片段

C#实现程序的版本升级更新

python之tcp自动重连

错误 3002:映射片段中的问题 | c# linq 到实体