IT实验室
1 前言
长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序可维护性差,布置困难,升级不方便,维护成本高就是一个相当重要的因素。有很多企业用户就是因为这个原因而放弃使用C/S。然而当一个应用必须要使用C/S结构才能很好的实现其功能的时候,我们该如何解决客户端的部署与自动升级问题?部署很简单,只要点击安装程序即可,难的在于每当有新版本发布时,能够实现自动升级[3]。现在好了,我们的目标很简单,我们希望开发一个与具体应用无关的能够复用的自动升级系统。下面我为大家提供了一套可复用的用C#编写的自动升级系统。
2 实现软件的自动升级存在的困难
第一,为了查找远程服务器上的更新,应用程序必须有查询网络的途径,这需要网络编程、简单的应用程序与服务器通讯的协议。
第二是下载。下载看起来不需要考虑联网的问题,但要考虑下载用户请求的文件,以及在没有用户同意时下载大文件。友好的自动更新应用程序将使用剩余的带宽下载更新。这听起来简单,但却是一个技术难题,幸运的是已经有了解决方法。
第三个考虑因素是使用新版应用程序更换原应用程序的过程。这个问题比较有趣,因为它要求代码运行时将自己从系统删除,有多种办法可以实现该功能[5],本文程序主要通过比较新旧版本的日期号来实现替换新版本应用程序的功能。
3 实现软件自动在线升级的原理
写两个程序,一个是主程序;一个是升级程序;所有升级任务都由升级程序完成。
1.启动升级程序,升级程序连接到网站,下载新的主程序(当然还包括支持的库文件、XML配置文档等)到临时文件夹;
2.升级程序获取服务器端XML配置文件中新版本程序的更新日期或版本号或文件大小;
3.升级程序获取原有客户端应用程序的最近一次更新日期或版本号或文件大小,两者进行比较;如果发现升级程序的日期大于原有程序的最新日期,则提示用户是否升级;或者是采用将现有版本与最新版本作比较,发现最新的则提示用户是否升级;也有人用其它属性如文件大小进行比较,发现升级程序的文件大小大于旧版本的程序的大小则提示用户升级。本文主要采用比较新旧版本更新日期号来提示用户升级。
4.如果用户选择升级,则获取下载文件列表,开始进行批量下载文档;
5.升级程序检测旧的主程序是否活动,若活动则关闭旧的主程序;
6.删除旧的主程序,拷贝临时文件夹中的文件到相应的位置;
7.检查主程序的状态,若状态为活动的,则启动新的主程序;
8.关闭升级程序,升级完成[4]。
4 用C#实现在线升级的关键步骤
这里我主要使用日期信息来检测是否需要下载升级版本。
4.1 准备一个XML配置文件
名称为AutoUpdater.xml,作用是作为一个升级用的模板,显示需要升级的信息。
名称为AutoUpdater.xml,作用是作为一个升级用的模板,显示需要升级的信息。
<?xml version="1.0"?> //xml版本号
<AutoUpdater>
<URLAddres URL="http://192.168.198.113/vbroker/log/"/>//升级文件所在服务器端的网址
<UpdateInfo>
<UpdateTime Date = "2005-02-02"/> //升级文件的更新日期
<Version Num = "1.0.0.1"/> //升级文件的版本号
</UpdateInfo>
<UpdateFileList> //升级文件列表
<UpdateFile FileName = "aa.txt"/> //共有三个文件需升级
<UpdateFile FileName = "VB40.rar"/>
<UpdateFile FileName = "VB4-1.CAB"/>
</UpdateFileList>
<RestartApp>
<ReStart Allow = "Yes"/> //允许重新启动应用程序
<AppName Name = "TIMS.exe"/> //启动的应用程序名
</RestartApp>
</AutoUpdater>
//xml版本号
//升级文件所在服务器端的网址
//升级文件的更新日期
//升级文件的版本号
//升级文件列表
//共有三个文件需升级
//允许重新启动应用程序
//启动的应用程序名
从以上XML文档中可以得知升级文档所在服务器端的地址、升级文档的更新日期、需要升级的文件列表,其中共有三个文件需升级:aa.txt、VB40.rar、VB4-1.CAB。以及是否允许重新启动应用程序和重新启动的应用程序名。
4.2 获取客户端应用程序及服务器端升级程序的最近一次更新日期
通过GetTheLastUpdateTime()函数来实现。
private string GetTheLastUpdateTime(string Dir)
{
string LastUpdateTime = "";
string AutoUpdaterFileName = Dir + @"\AutoUpdater.xml";
if(!File.Exists(AutoUpdaterFileName))
return LastUpdateTime;
//打开xml文件
FileStream myFile = new FileStream(AutoUpdaterFileName,FileMode.Open);
//xml文件阅读器
XmlTextReader xml = new XmlTextReader(myFile);
while(xml.Read())
{
if(xml.Name == "UpdateTime")
{
//获取升级文档的最后一次更新日期
LastUpdateTime = xml.GetAttribute("Date");
break;
}
}
xml.Close();
myFile.Close();
return LastUpdateTime;
}
通过XmlTextReader打开XML文档,读取更新时间从而获取Date对应的值,即服务器端升级文件的最近一次更新时间。
函数调用实现:
//获取客户端指定路径下的应用程序最近一次更新时间
string thePreUpdateDate = GetTheLastUpdateTime(Application.StartupPath);
Application.StartupPath指客户端应用程序所在的路径。
//获得从服务器端已下载文档的最近一次更新日期
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
theFolder.FullName指在升级文档下载到客户机上的临时文件夹所在的路径。
4.3 比较日期
客户端应用程序最近一次更新日期与服务器端升级程序的最近一次更新日期进行比较。
//获得已下载文档的最近一次更新日期
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
if(thePreUpdateDate != "")
{
//如果客户端将升级的应用程序的更新日期大于服务器端升级的应用程序的更新日期
if(Convert.ToDateTime(thePreUpdateDate)>=Convert.ToDateTime(theLastsUpdateDate))
{
MessageBox.Show("当前软件已经是最新的,无需更新!","系统提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
this.Close();
}
}
this.labDownFile.Text = "下载更新文件";
this.labFileName.Refresh();
this.btnCancel.Enabled = true;
this.progressBar.Position = 0;
this.progressBarTotal.Position = 0;
this.progressBarTotal.Refresh();
this.progressBar.Refresh();
//通过动态数组获取下载文件的列表
ArrayList List = GetDownFileList(GetTheUpdateURL(),theFolder.FullName);
string[] urls = new string[List.Count];
List.CopyTo(urls, 0);
将客户端升级的应用程序的日期与服务器端下载的应用程序日期进行比较,如果前者大于后者,则不更新;如果前者小于后者,则通过动态数组获取下载文件的列表,开始下载文件。
4.2 获取客户端应用程序及服务器端升级程序的最近一次更新日期
通过GetTheLastUpdateTime()函数来实现。
private string GetTheLastUpdateTime(string Dir)
{
string LastUpdateTime = "";
string AutoUpdaterFileName = Dir + @"\AutoUpdater.xml";
if(!File.Exists(AutoUpdaterFileName))
return LastUpdateTime;
//打开xml文件
FileStream myFile = new FileStream(AutoUpdaterFileName,FileMode.Open);
//xml文件阅读器
XmlTextReader xml = new XmlTextReader(myFile);
while(xml.Read())
{
if(xml.Name == "UpdateTime")
{
//获取升级文档的最后一次更新日期
LastUpdateTime = xml.GetAttribute("Date");
break;
}
}
xml.Close();
myFile.Close();
return LastUpdateTime;
}
通过XmlTextReader打开XML文档,读取更新时间从而获取Date对应的值,即服务器端升级文件的最近一次更新时间。
函数调用实现:
//获取客户端指定路径下的应用程序最近一次更新时间
string thePreUpdateDate = GetTheLastUpdateTime(Application.StartupPath);
Application.StartupPath指客户端应用程序所在的路径。
//获得从服务器端已下载文档的最近一次更新日期
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
theFolder.FullName指在升级文档下载到客户机上的临时文件夹所在的路径。
4.3 比较日期
客户端应用程序最近一次更新日期与服务器端升级程序的最近一次更新日期进行比较。
//获得已下载文档的最近一次更新日期
string theLastsUpdateDate = GetTheLastUpdateTime(theFolder.FullName);
if(thePreUpdateDate != "")
{
//如果客户端将升级的应用程序的更新日期大于服务器端升级的应用程序的更新日期
if(Convert.ToDateTime(thePreUpdateDate)>=Convert.ToDateTime(theLastsUpdateDate))
{
MessageBox.Show("当前软件已经是最新的,无需更新!","系统提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
this.Close();
}
}
this.labDownFile.Text = "下载更新文件";
this.labFileName.Refresh();
this.btnCancel.Enabled = true;
this.progressBar.Position = 0;
this.progressBarTotal.Position = 0;
this.progressBarTotal.Refresh();
this.progressBar.Refresh();
//通过动态数组获取下载文件的列表
ArrayList List = GetDownFileList(GetTheUpdateURL(),theFolder.FullName);
string[] urls = new string[List.Count];
List.CopyTo(urls, 0);
将客户端升级的应用程序的日期与服务器端下载的应用程序日期进行比较,如果前者大于后者,则不更新;如果前者小于后者,则通过动态数组获取下载文件的列表,开始下载文件。
通过BatchDownload()函数来实现。升级程序检测旧的主程序是否活动,若活动则关闭旧的主程序;删除旧的主程序,拷贝临时文件夹中的文件到相应的位置;检查主程序的状态,若状态为活动的,则启动新的主程序。
private void BatchDownload(object da<wbr>ta) </wbr>
{
this.Invoke(this.activeStateChanger, new object[]{true, false});
try
{
DownloadInstructions instructions = (DownloadInstructions) da<wbr>ta; </wbr>
//批量下载
using(BatchDownloader bDL = new BatchDownloader())
{
bDL.CurrentProgressChanged += new DownloadProgressHandler(this.SingleProgressChanged);
bDL.StateChanged += new DownloadProgressHandler(this.StateChanged);
bDL.FileChanged += new DownloadProgressHandler(bDL_FileChanged);
bDL.TotalProgressChanged += new DownloadProgressHandler(bDL_TotalProgressChanged);
bDL.Download(instructions.URLs, instructions.Destination, (ManualResetEvent) this.cancelEvent);
}
}
catch(Exception ex)
{
ShowErrorMessage(ex);
}
this.Invoke(this.activeStateChanger, new object[]{false, false});
this.labFileName.Text = "";
//更新程序
if(this._Update)
{
//关闭原有的应用程序
this.labDownFile.Text = "正在关闭程序....";
System.Diagnostics.Process[]proc=System.Diagnostics.Process.GetProcessesByName("TIMS");
//关闭原有应用程序的所有进程
foreach(System.Diagnostics.Process pro in proc)
{
pro.Kill();
}
DirectoryInfo theFolder=new DirectoryInfo(Path.GetTempPath()+"JurassicUpdate");
if(theFolder.Exists)
{
foreach(FileInfo theFile in theFolder.GetFiles())
{
//如果临时文件夹下存在与应用程序所在目录下的文件同名的文件,则删除应用程序目录下的文件
if(File.Exists(Application.StartupPath + \\"+Path.GetFileName(theFile.FullName)))
File.Delete(Application.StartupPath + "\\"+Path.GetFileName(theFile.FullName));
//将临时文件夹的文件移到应用程序所在的目录下
File.Move(theFile.FullName,Application.StartupPath + \\"+Path.GetFileName(theFile.FullName));
}
}
//启动安装程序
this.labDownFile.Text = "正在启动程序....";
System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "TIMS.exe");
this.Close();
}
}
这段程序是实现在线升级的关键代码,步骤有点复杂:首先用Invoke方法同步调用状态改变进程,然后调用动态链接库中批量下载(BatchDownloader.cs)类启动批量下载,接着判断原有的主应用程序有没有关闭,如果没关闭,则用Process.Kill()来关闭主程序。接下来,判断临时文件夹下(即下载升级程序所在的目录)是否存在与应用程序所在目录下的文件同名的文件,如果存在同名文件,则删除应用程序目录下的文件,然后将临时文件夹的文件移到应用程序所在的目录下。最后重新启动主应用程序。这样更新就完成了。
分享到:
相关推荐
C#实现软件自动更新程序 概述 本文将介绍使用 C# 实现软件自动更新程序的关键步骤。该程序通过读取 XML 配置文件来检测是否需要下载升级版本,并实现自动更新功能。 XML 配置文件 在本程序中,我们使用 XML 配置...
【C#实现软件自动更新和升级发布】 在软件开发中,自动更新功能是提高用户体验、确保用户始终使用最新版本的重要手段。使用C#语言来实现这一功能,可以使开发者更便捷地管理和分发软件更新,避免用户手动下载和安装...
C#实现软件自动更新思路分享.pdf 本文主要讨论了使用C#语言实现软件自动更新的思路和实现方法。作者首先提出了使用C/S结构的程序维护性差、布置困难、升级不方便、维护成本高的问题,然后提出了使用C#语言实现自动...
WPF软件自动更新程序,任何C#程序都可以引用此程序来实现软件的版本检查及自动更新,使用介绍:https://blog.csdn.net/u011373615/article/details/133940461
"C#程序自动更新 可实现自身更新"这个主题涉及到的是一个关键的软件工程实践——自动更新机制。这种机制允许软件在后台检查并下载最新的版本,然后在用户方便时或在程序启动时进行安装,从而确保用户始终运行的是...
本示例("C#程序自动更新")探讨了如何在C#应用程序中实现一个简单的自动更新功能。 首先,我们要理解自动更新的基本流程。这个过程通常包括以下几个步骤: 1. **检查更新**:应用程序启动时或用户触发时,程序会...
以下是一个基于C#的软件自动更新的解决思路: 首先,我们需要创建两个独立的exe文件,一个是主程序,另一个是更新程序。主程序是用户日常使用的应用程序,而更新程序则负责检查新版本并执行升级操作。更新程序应...
### C#实现在线软件自动升级程序 #### 一、架构设计与需求分析 在开发一个在线软件自动升级系统时,首先需要明确其架构设计以及具体的需求。通常来说,这种系统可以基于Client/Server (C/S) 架构或Browser/Server ...
【采用C#实现软件自动更新的方法】 在C#编程中,软件自动更新是解决C/S架构应用程序维护性和升级便利性问题的重要技术。由于C/S结构的程序在维护、部署和升级方面存在诸多挑战,开发者们一直在寻找解决方案。本文将...
总的来说,C#实现软件自动升级是一个涉及网络通信、文件操作、解压缩和流程控制的综合性任务。通过合理利用C#提供的类库和工具,我们可以构建出稳定、可靠的自动升级机制,为用户提供无痛的更新体验。在实际开发中,...
总结来说,C#实现自动更新涉及网络请求、文件操作、版本控制等多个方面,通过合理的编程和设计,可以为用户提供无缝的更新体验。在实际开发中,还需要考虑安全性、用户体验以及各种可能的异常情况,以确保自动更新...
在本文中,我们将深入探讨如何使用C#编程语言通过FTP(File Transfer Protocol)协议实现客户端程序的自动更新功能。此技术对于确保用户始终运行应用程序的最新版本至关重要,从而提高用户体验和安全性。 首先,...
本篇将详细讲解基于C#实现的FTP自动更新模块,结合提供的源码,我们将探讨其中的关键技术和实现原理。 首先,"FTP自动更新模块"是指通过FTP协议从服务器下载最新版本的程序或资源文件,然后在本地进行安装或覆盖,...
这个“c#软件自动更新源码”项目利用.NET Framework 2.0,提供了一个简洁有效的解决方案来实现软件的自动更新。下面将详细探讨相关知识点。 首先,我们要了解.NET Framework 2.0。它是微软开发的一个框架,用于构建...
当前资源在后续更新会以私信的方式发送,已经购买资源的朋友请不要取关,谢谢了 帖子地址: https://blog.csdn.net/qq_38693757/article/details/131223450?spm=1001.2014.3001.5502 具体的介绍请看帖子,这里文字...
本主题聚焦于"C#程序自动远程更新"这一重要技术,它允许应用程序在运行时检查并安装远程服务器上的最新版本,从而确保用户始终使用的是最新的软件功能,并解决了安全性和错误修复的问题。 一、自动更新机制 自动...
本资源聚焦于使用C#语言实现自动更新功能,特别是针对基于CS(Client-Server)框架的应用程序。C#是一种广泛使用的编程语言,尤其在Windows桌面应用开发中占据主导地位。下面将详细介绍如何利用C#来构建自动更新系统...
本资源包含了关于如何在C#环境中构建自动更新机制的详细资料,包括一个名为“在C#中实现软件自动升级.doc”的文档,以及指向更多免费资源的链接:“更多免费精品资源:点击访问.url”。 首先,我们需要理解自动升级...
在C/S(客户端/服务器)模式下,软件自动在线升级是一项关键功能,它允许应用程序能够自动检查并安装最新的更新,从而提高用户体验并确保系统的安全性。本篇将详细讲解如何使用C#来实现这一功能,同时利用XML作为...