惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
Y
Y Combinator Blog
美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
S
SegmentFault 最新的问题
IT之家
IT之家
Recent Announcements
Recent Announcements
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
Martin Fowler
Martin Fowler
Microsoft Azure Blog
Microsoft Azure Blog
V
Visual Studio Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
WordPress大学
WordPress大学
博客园 - Franky
L
LangChain Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
博客园 - 叶小钗
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
雷峰网
雷峰网
腾讯CDC
Google DeepMind News
Google DeepMind News
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Help Net Security
Help Net Security
C
Check Point Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
News and Events Feed by Topic
V2EX - 技术
V2EX - 技术
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Schneier on Security
Schneier on Security
博客园 - 聂微东
A
Arctic Wolf
H
Heimdal Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
The Exploit Database - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google DeepMind News
Google DeepMind News

博客园 - 海浪~~

[转]Visual Studio 2008 每日提示系列索引 取消“解决方案资源管理器”自动跟随 【转】ie6.0下div 不能实现1px 高度的几种解决方法 - 海浪~~ 【转】IE6下div边框显示 不完整有残缺 【转】IE6下IMG下出现空白条的解决方法汇总 【转】enter键转tab键 (支持ie,ff,chrome) - 海浪~~ - 博客园 【转】安装 SQL Server 2008 的硬件和软件要求 【转】sql语句优化工具LECCO SQL Expert 版本自动更新程序及3种实现策略(二)下载器实现 版本自动更新程序及3种实现策略-分析文档(UML图) SQL SERVER 获取表结构信息《转载》 某知名公司ERP数据库结构[6] 某知名公司ERP数据库结构[5] 某知名公司ERP数据库结构[4] 某知名公司ERP数据库结构[3] 某知名公司ERP数据库结构[2] 某知名公司ERP数据库结构[1] 关于VS2008调试时端口号不一致的问题(ZT) [导入]Asp.net 2.0 C#实现压缩/解压功能 (示例代码下载) [导入]Asp.net 2.0 实现自定义Email格式有效性验证(示例代码下载) [导入]Asp.net 2.0 GridView数据导出Excel文件(示例代码下载) [导入]AjaxPro.NET框架生成高效率的Tree(Asp.net 2.0)(示例代码下载) [导入]AjaxPanel自定义控件实现页面无刷新数据交互(做了个示例程序, 效果确实比较Cool, 用法非常简单! )(示例代码下载) [导入]Asp.net 2.0 制作最原始的TextBox控件[一](示例代码下载) [导入]Asp.net 2.0 一个简单的联动DropDownList示例(示例代码下载) [导入]ASP.NET 2.0 HttpHandler实现生成图片验证码(示例代码下载) [导入]ASP.NET 2.0 读取配置文件[INI](示例代码下载) [导入]Asp.net 2.0 用C# 创建 PDF文件[引用] (示例代码下载) [导入]Ajax 实现在WebForm中拖动控件并即时在服务端保存状态数据 (Asp.net 2.0)(示例代码下载) [导入]Asp.net 2.0 制作复合控件示例(二)[示例代码下载] [导入]Asp.net 2.0 文件下载[支持多线程, 断点续传功能](示例代码下载) [导入]JavaScript组件之JQuery(A~Z)教程(基于Asp.net运行环境)[示例代码下载]
版本自动更新程序及3种实现策略程序下载(附源码)
海浪~~ · 2009-09-25 · via 博客园 - 海浪~~

http://www.vjsdn.com/bbs/bbsTopicDetails.aspx?pid=611


版本自动更新程序及3种实现策略(一)文档及UML图

版本自动更新程序及3种实现策略(二)下载器实现 

程序界面及系统设置
贴图图片
图1-版本升级程序服务器端设置
1. 服务器端程序发布URL地址,该参数用于Web下载器连接的url地址。
2. 服务器端程序发布目录,用于tcp/ip下载器下载的目录。
3. 服务器端程序共享目录,用于Lan下载器下载的目录.
以前3个参数跟据选择的下载器类型做相应设置。

贴图图片
图2-本机配置
本地程序发布目录:用于任一下载器下载文件后存放文件的目录。

贴图图片
图3-下载器设置(更新参数设置,未改名)
选择三种下载器中任何一种作为当前下载器。

贴图图片
图4-Tcp/Ip下载器服务器程序.
当您选择Tcp/Ip下载器升级程序,请先运行服务器端程序。
 
贴图图片
图5-版本自动升级程序主界面

运行程序前先要配置系统参数,配置文件保存在程序运行目录下的upgrader.dat文件。参考上面的所介绍的系统设置界面。跟据选择的下载器类型作相应配置。

如出现以下提示,说明您还没有配置程序目录下无upgrader.dat文件.
贴图图片
图6-没有配置文件提示窗体

服务器程序发布目录结构如下图:
 贴图图片
图7-服务器程序发布目录结构

D:\Shared\是服务器上的目录,该目录存放最新版本文件及XmlServerFiles.xml 文件清单。
清单文件可以通过枚举目录下包括子目录下所有文件自动生成,下次更新版本时只需调整某几项内容。

XmlServerFiles.xml 文件内容

<?xml version="1.0" encoding="utf-8" ?>
<Upgrader>
<description>服务器端文件清单</description>
<Application>
<!--程序最新版本发布时间-->
<LastUpdateTime value="4/26/2007 10:30:32 AM" />
<!--版本号-->
<Version value="1.2.1" />
</Application>
<Files>
<File fullPath=".\Web3Layers.rar" fileName="Web3Layers.rar" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\ip_setup.txt" fileName="ip_setup.txt" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\a.png" fileName="a.png" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\mdimain2.png" fileName="mdimain2.png" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\KAV8.0-Key.R00" fileName="KAV8.0-Key.R00" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\crossthread.png" fileName="crossthread.png" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\newfolder\kav.rar" fileName="kav.rar" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\a\crossthread.png" fileName="crossthread.png" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\VJSDN.Tech.AutoUpgrader.exe" fileName="VJSDN.Tech.AutoUpgrader.exe" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\VJSDN.Tech.AutoUpgradeServer.exe" fileName="VJSDN.Tech.AutoUpgradeServer.exe" lastModify="4/26/2009 9:53:23 AM" />
<File fullPath=".\VJSDN.Tech.AutoUpgraderLib.dll" fileName="VJSDN.Tech.AutoUpgraderLib.dll" lastModify="4/26/2009 9:53:23 AM" />
</Files>
</Upgrader>


AppSettings.cs 系统参数代码实现(序列化对象保存为文件)

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace VJSDN.Tech.AutoUpgraderLib
{
    
    
    
   [Serializable]
   public class AppSettings
   {
      private string _ServerSharedFolder = "";
      private string _ServerIP = "";
      private int _ServerPort = 0;
      private string _ServerFilesXml = "";
      private string _ServerPublishFolder = "";  
      private string _ServerPublishUrl = "";
      private string _ClientSaveFolder = "";
      private string _ClientFilesXml = "";
      private int _DownloaderType = 0;
      
      
      private static AppSettings _instance = null;
      
       
       
       
      public static AppSettings Instance
      {
         get
         {
            if (_instance == null) CreateDefault();
            return _instance;
         }
      }
      
      private static void CreateDefault()
      {
         _instance = new AppSettings();
         _instance.ServerFilesXml = "XmlServerFiles.xml";
         _instance.ServerSharedFolder = @"\\192.168.1.2\Shared";
         _instance.ServerPublishUrl = "http://www.vjsdn.com/UserUpload";
         _instance.ServerPublishFolder = @"d:\mypublish\autoupgrader";
         _instance.ServerIP = "192.168.1.1";
         _instance.ServerPort = 12345;
         _instance.DownloaderType = (int)DownloadType.Intranet;
         _instance.ClientFilesXml = "XmlClientFiles.xml";
         _instance.ClientSaveFolder = @"c:\yourfolder\newversion";
         
      }
      
      public static bool HasSetting()
      {
         string file = Application.StartupPath + @"\upgrader.dat";
         return File.Exists(file);
      }
      
       
       
       
      public static void Read()
      {
         string file = Application.StartupPath + @"\upgrader.dat";
         if (File.Exists(file))
         {
            FileStream fs = File.Open(file, FileMode.OpenOrCreate, FileAccess.Read);
            byte[] bs = new byte[fs.Length];
            int len = fs.Read(bs, 0, bs.Length);
            if (len > 0)
            {
               object o = ZipObject.DecompressionObject(bs);
               _instance = (AppSettings)o;
            }
            fs.Close();
         }
      }
      
       
       
       
      public static void Write()
      {
         string file = Application.StartupPath + @"\upgrader.dat";
         FileStream fs = File.Open(file, FileMode.OpenOrCreate, FileAccess.Write);
         byte[] bs = ZipObject.CompressionObject(_instance);
         fs.Write(bs, 0, bs.Length);
         fs.Flush();
         fs.Close();
      }
      
       
       
       
      public string ServerSharedFolder { get { return _ServerSharedFolder; } set { _ServerSharedFolder = value; } }
      
       
       
       
      public string ServerIP { get { return _ServerIP; } set { _ServerIP = value; } }
      
       
       
       
      public int ServerPort { get { return _ServerPort; } set { _ServerPort = value; } }
      
       
       
       
      public int DownloaderType { get { return _DownloaderType; } set { _DownloaderType = value; } }
      
       
       
       
      public string ServerPublishUrl { get { return _ServerPublishUrl; } set { _ServerPublishUrl = value; } }
      
       
       
       
      public string ServerPublishFolder { get { return _ServerPublishFolder; } set { _ServerPublishFolder = value; } }
      
       
       
       
      public string ClientSaveFolder { get { return _ClientSaveFolder; } set { _ClientSaveFolder = value; } }
      
       
       
       
      public string ClientFilesXml { get { return _ClientFilesXml; } set { _ClientFilesXml = value; } }
      
       
       
       
      public string ServerFilesXml { get { return _ServerFilesXml; } set { _ServerFilesXml = value; } }
      
   }
}


Common.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;

namespace VJSDN.Tech.AutoUpgraderLib
{
   public class Common
   {
       
      public static DateTime StrToDate(string date)
      {
         DateTime ret = DateTime.MinValue;
         if (DateTime.TryParse(date, out ret))
         return ret;
         else
         return DateTime.MinValue;
      }
   }
   
   
   
   
   public class ZipObject
   {
      public static byte[] CompressionObject(object DataOriginal)
      {
         if (DataOriginal == nullreturn null;
         BinaryFormatter bFormatter = new BinaryFormatter();
         MemoryStream mStream = new MemoryStream();
         bFormatter.Serialize(mStream, DataOriginal);
         byte[] bytes = mStream.ToArray();
         MemoryStream oStream = new MemoryStream();
         DeflateStream zipStream = new DeflateStream(oStream, CompressionMode.Compress);
         zipStream.Write(bytes, 0, bytes.Length);
         zipStream.Flush();
         zipStream.Close();
         return oStream.ToArray();
      }
      
      public static object DecompressionObject(byte[] bytes)
      {
         if (bytes == nullreturn null;
         MemoryStream mStream = new MemoryStream(bytes);
         mStream.Seek(0, SeekOrigin.Begin);
         DeflateStream unZipStream = new DeflateStream(mStream, CompressionMode.Decompress, true);
         object dsResult = null;
         BinaryFormatter bFormatter = new BinaryFormatter();
         dsResult = (object)bFormatter.Deserialize(unZipStream);
         return dsResult;
      }
   }
}


FileView.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Threading;

namespace VJSDN.Tech.AutoUpgraderLib
{
    
    
    
   public class FileView
   {
      private XmlLoader _xml = null;
      private ToolStripProgressBar _progress = null;
      
      public FileView(XmlLoader xml, ToolStripProgressBar progress)
      {
         _xml = xml;
         _progress = progress;
      }
      
       
      public void LoadTreeViewServer(TreeView treeView)
      {
         treeView.Nodes.Clear();
         XmlNode node = _xml.XML.SelectSingleNode("Upgrader/Files");
         if (node == nullthrow new Exception("找不到xml文件的Upgrader/Files结点!");
         _progress.Maximum = node.ChildNodes.Count + 1;
         _progress.Minimum = 1;
         _progress.Value = 1;
         
         foreach (XmlNode n in node.ChildNodes)
         {
            CreateNode(treeView, n, null);
            _progress.Value++;
         }
      }
      
       
      public void LoadTreeViewClient(TreeView treeView, XmlLoader server)
      {
         treeView.Nodes.Clear();
         XmlNode node = _xml.XML.SelectSingleNode("Upgrader/Files");
         if (node == nullthrow new Exception("找不到xml文件的Upgrader/Files结点!");
         _progress.Maximum = node.ChildNodes.Count + 1;
         _progress.Minimum = 1;
         _progress.Value = 1;
         
         foreach (XmlNode n in node.ChildNodes)
         {
            CreateNode(treeView, n, server);
            _progress.Value++;
         }
         
          
         if (_xml.HasNewVersion == false && server != null && _xml.FilesCount < server.FilesCount)
         _xml.HasNewVersion = true;
      }
      
      private void CreateNode(TreeView treeView, XmlNode n, XmlLoader comparer)
      {
          
          
         string fullPath = n.Attributes["fullPath"].Value;
         string[] part = fullPath.Split(new char[] { char.Parse(@"\") });
         TreeNode currNode = null;
         foreach (string p in part)
         {
            if (p == ".") continue
            if (p.Length > 3 && p.IndexOf(".") > 0) //文件
            {
               TreeNode node = new TreeNode(p);
               
               if (comparer == null)
               node.ImageIndex = 0;  
               else
               {
                  XmlNode node2 = comparer.GetFileNode(fullPath);
                  
                  if (_xml.CompareNode(node2, n))
                  {
                     node.ImageIndex = 2;
                     node.SelectedImageIndex = 2;
                     _xml.HasNewVersion = true;
                  }
                  else
                  node.ImageIndex = 0;
               }
               
               if (currNode == null)
               treeView.Nodes.Add(node);  
               else
               currNode.Nodes.Add(node); 
               
               return;
            }
            else //子目录
            {
               TreeNode tempNode = FindNode(treeView, currNode, p);  
               
               if (tempNode == null) //未找到结点.则创建结点
               {
                  TreeNode tmp = new TreeNode(p);
                  tmp.ImageIndex = 1; 
                  if (currNode == null)
                  treeView.Nodes.Add(tmp);  
                  else
                  currNode.Nodes.Add(tmp);  
                  
                  currNode = tmp;
               }
               else
               currNode = tempNode;  
            }
         }
      }
      
       
      private TreeNode FindNode(TreeView treeView, TreeNode currNode, string text)
      {
         if (currNode == null) //在根目录搜索
         {
            foreach (TreeNode node in treeView.Nodes)
            if (node.Text.ToUpper() == text.ToUpper()) return node;
         }
         else //在当前目录搜索
         {
            foreach (TreeNode node in currNode.Nodes)
            if (node.Text.ToUpper() == text.ToUpper()) return node; 
         }
         return null;  
      }
   }
}


UpgraderClient.cs

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

namespace VJSDN.Tech.AutoUpgraderLib
{
    
    
    
   public class UpgraderClient
   {
      private OutputInvoke _writeOutput = null;
      
      public UpgraderClient(OutputInvoke writeOutput)
      {
         _writeOutput = writeOutput;
      }
      
      private TcpClient _Client = null;
      private TcpClient Client
      {
         get
         {
            if (_Client == null)
            {
               _Client = new TcpClient();
            }
            return _Client;
         }
      }
      
      public void CloseClient()
      {
         if (_Client != null && _Client.Connected) _Client.Close();
      }
      
       
       
       
      public bool DownloadFile(string file, string savePath)
      {
         try
         {
            TcpClient client = new TcpClient();
             
            
            if (client == null || file.Trim() == "") return false;
            
            TryConnect(client, AppSettings.Instance.ServerIP, AppSettings.Instance.ServerPort);  
            if (!client.Connected) return false
            
            byte[] bs = Encoding.Unicode.GetBytes("GET_FILE|" + file);
            client.Client.Send(bs);  
            
             
            NetworkStream ns = client.GetStream();
            MemoryStream ms = new System.IO.MemoryStream();
            
            byte[] resBytes = new byte[256];  
            int resSize;  
            do
            {
                
               resSize = ns.Read(resBytes, 0, resBytes.Length);
               
               string msg = Byte2Str(resBytes);
               if (msg.Trim().ToUpper() == "FILE_NOT_FOUND")
               {
                  if (_writeOutput != null) _writeOutput("找不到文件:" + file);
                  break;
               }
               if (resSize == 0) break;
               
               ms.Write(resBytes, 0, resSize);
               } while (ns.DataAvailable);
               ns.Close();  
               
               if (ms.Length > 0)
               {
                  FileStream fs = File.Open(savePath, FileMode.OpenOrCreate, FileAccess.Write);
                  fs.Write(ms.ToArray(), 0, (int)ms.Length);
                  fs.Flush();
                  fs.Close(); 
                  if (_writeOutput != null) _writeOutput("文件已下载:" + file);
               }
               
               ms.Close(); 
               client.Close(); 
               return true;
            }
            catch
            {
               return false;
            }
         }
         
         private string Byte2Str(byte[] buffer)
         {
            string msg = Encoding.Unicode.GetString(buffer).Replace("\0", "");
            return msg.Trim();
         }
         
         private void TryConnect(TcpClient client, string hostIP, int hostPort)
         {
            try
            {
               client.Connect(IPAddress.Parse(hostIP), hostPort);  
            }
            catch
            {
               throw new Exception("主机已关闭或网络存在问题,不能建立连线!");
            }
         }
      }
   }


UpgraderServer.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Windows.Forms;
using System.IO;

namespace VJSDN.Tech.AutoUpgraderLib
{
   
    
   public delegate void OutputInvoke(string msg);
   
    
    
    
   public class UpgraderServer
   {
      private TcpListener _ServerListener = null;  
      private Thread _ServerListenerThread = null;  
      private bool _ServerRunning = false;
      
      private Form _owner = null;
      private OutputInvoke _writeOutput = null;
      
      public UpgraderServer(Form owner, OutputInvoke method)
      {
         _owner = owner;
         _writeOutput = method;
      }
      
      
      public void StartListening(string ip, int port)
      {
         if (_ServerRunning) return;
         
          
         _ServerListener = new TcpListener(IPAddress.Parse(ip), port);
         _ServerListener.Start(255);
         _ServerRunning = true;
         
          
         _ServerListenerThread = new Thread(new ThreadStart(DoStartServerListener));
         _ServerListenerThread.IsBackground = true;
         _ServerListenerThread.Start();
      }
      
      
      public void Stop()
      {
         _ServerRunning = false;
         _ServerListenerThread.Abort(101);
         _ServerListenerThread = null;
         _ServerListener.Stop();
      }
      
       
       
       
      private void DoStartServerListener()
      {
         
         while (_ServerRunning)
         {
            try
            {
               if (_ServerListener == nullreturn;  
               Application.DoEvents();
               Socket socket = _ServerListener.AcceptSocket();  
               if (socket == nullcontinue;
               
               byte[] buffer = new Byte[socket.ReceiveBufferSize];
               int i = socket.Receive(buffer);  
               if (i <= 0) continue;
               
               string msg = Encoding.Unicode.GetString(buffer).Replace("\0", "");
               msg = msg.Trim();
               if (msg.ToUpper().StartsWith("GET_FILE")) //命令字符串:GET_FILE|.\a.dll
               {
                  string[] sps = msg.Split(new char[] { char.Parse("|") });
                  string file = sps[1]; 
                  this.SendFile(socket, file);
               }
               socket.Close(); 
            }
            catch (Exception ex)
            {
               if (ex is ThreadAbortException)
               {
                  if ((ex as ThreadAbortException).ExceptionState.ToString() == "101")
                  {
                     _ServerRunning = false;
                     ShowLog("用户关闭服务器.");
                  }
                  else
                  ShowLog(ex.Message);
               }
               else
               {
                  ShowLog(ex.Message);
               }
            }
         }
      }
      
      private void SendFile(Socket socket, string file)
      {
         if (File.Exists(file))
         {
            ShowLog("获取文件[" + file + "]....");
            socket.SendFile(file);
            ShowLog("[" + file + "]已发送.");
         }
         else
         {
            socket.Send(Encoding.Unicode.GetBytes("FILE_NOT_FOUND"));  
            ShowLog("[" + file + "]不存在.");
         }
      }
      
       
      private void ShowLog(string log)
      {
          
         _owner.Invoke(_writeOutput, log);
      }
   }
}


解决方案视图:
贴图图片
附件已打包下面的源代码:
VJSDN.Tech.AutoUpgrader.exe 自动升级程序主程序
VJSDN.Tech.AutoUpgradeServer.exe tcp/ip下载器服务器程序

VJSDN.Tech.AutoUpgraderLib.dll 内的文件已分散在3个帖内

******* 请在运行程序前先配置系统参数 *******

该帖子最后修改:2009-8-13 15:25:16