

























http://www.vjsdn.com/bbs/bbsTopicDetails.aspx?pid=611
版本自动更新程序及3种实现策略(二)下载器实现
运行程序前先要配置系统参数,配置文件保存在程序运行目录下的upgrader.dat文件。参考上面的所介绍的系统设置界面。跟据选择的下载器类型作相应配置。 如出现以下提示,说明您还没有配置程序目录下无upgrader.dat文件.
服务器程序发布目录结构如下图: XmlServerFiles.xml 文件内容 <?xml version="1.0" encoding="utf-8" ?> using System;
namespace VJSDN.Tech.AutoUpgraderLib using System;
namespace VJSDN.Tech.AutoUpgraderLib using System;
namespace VJSDN.Tech.AutoUpgraderLib using System;
namespace VJSDN.Tech.AutoUpgraderLib using System;
namespace VJSDN.Tech.AutoUpgraderLib
VJSDN.Tech.AutoUpgraderLib.dll 内的文件已分散在3个帖内 该帖子最后修改:2009-8-13 15:25:16
程序界面及系统设置

图1-版本升级程序服务器端设置
1. 服务器端程序发布URL地址,该参数用于Web下载器连接的url地址。
2. 服务器端程序发布目录,用于tcp/ip下载器下载的目录。
3. 服务器端程序共享目录,用于Lan下载器下载的目录.
以前3个参数跟据选择的下载器类型做相应设置。
图2-本机配置
本地程序发布目录:用于任一下载器下载文件后存放文件的目录。
图3-下载器设置(更新参数设置,未改名)
选择三种下载器中任何一种作为当前下载器。
图4-Tcp/Ip下载器服务器程序.
当您选择Tcp/Ip下载器升级程序,请先运行服务器端程序。

图5-版本自动升级程序主界面

图6-没有配置文件提示窗体

图7-服务器程序发布目录结构
D:\Shared\是服务器上的目录,该目录存放最新版本文件及XmlServerFiles.xml 文件清单。
清单文件可以通过枚举目录下包括子目录下所有文件自动生成,下次更新版本时只需调整某几项内容。
<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.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
{
[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.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;
{
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 == null) return 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 == null) return 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.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Threading;
{
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 == null) throw 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 == null) throw 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.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
{
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.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Windows.Forms;
using System.IO;
{
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 == null) return;
Application.DoEvents();
Socket socket = _ServerListener.AcceptSocket();
if (socket == null) continue;
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下载器服务器程序
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。