.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(); }
第二步:客户端创建服务连接,不多说,大家应该都会
第三步:客户端选择更新文件(包括了一个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
第四步:上传更新文件,采用数据序列化并压缩后上传
#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
第五步:服务端接受数据并写文件,修改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
第六步:客户端检测版本号,更新程序
#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
大致就是以上步骤。具体中的类等信息没有在代码中贴出,可以下载源代码进行研究。
缺陷:
第一:客户端调用没有判断服务是否开启
第二:文件存放路径还没写完整
第三:暂时自己大脑没想到。
源码下载https://yunpan.cn/cSbKnajf63ptA 访问密码 42ac