如何让客户端程序 自动更新 版本

如何让客户端程序 自动更新 版本,第1张

用C#实现软件自动更新思路

前言

长期以来,广大程序员为到底是使用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 data)

{

this.Invoke(this.activeStateChanger, new object[]{true, false})

try

{

DownloadInstructions instructions = (DownloadInstructions) data

//批量下载

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()

}

}

regsvr32命令

这里有很多Regsvr32命令,看了后就明白了 Regsvr32命令修复系统故障实例使用过activex的人都知道,activex不注册是不能够被系统识别和使用的,一般安装程序都会自动地把它所使用的activex控件注册,但如果你拿到的一个控件需要手动注册怎么办呢?如果修改注册表那就太麻烦了,在windows的system文件夹下有一个regsvr32.exe的程序,它就是windows自带的activex注册和反注册工具。

2000系统的regsvr32.exe在winnt\system32文件夹下;

WInXP系统的regsvr32.exe在windows\system32文件夹下

regsvr32的用法为:

"regsvr32 [/s] [/n] [/i(:cmdline)] dllname”。其中dllname为activex控件文件名,建议在安装前拷贝到system文件夹下。

参数有如下意义:

/u——反注册控件

/s——不管注册成功与否,均不显示提示框

/c——控制台输出

/i——跳过控件的选项进行安装(与注册不同)

/n——不注册控件,此选项必须与/i选项一起使用

执行该命令的方法:

1、可以在“开始”--“运行”,调出运行的对话框,也可以使用Win+R热键,然后直接在输入栏输入即可

2、在开始--运行 输入cmd,调出‘命令提示符’窗口,然后再执行regsvr32命令。

二、Regsvr32错误消息的说明

当使用 Regsvr32.exe 时,它会尝试加载该组件并调用它的 DLLSelfRegister 函数。如果此尝试成功,Regsvr32.exe 会显示一个指示成功的对话框。如果此尝试失败,Regsvr32.exe 会返回一条错误消息,其中可能会包括一个 Win32 错误代码。

以下列表介绍了 RegSvr32 错误消息和可能的原因。

Unrecognized flag:/invalid_flag

键入的标志或开关组合无效(请参阅本文中的“Regsvr32.exe 的用法”一节)。

No DLL name specified.

未包括 .dll 文件名(请参阅本文中的“Regsvr32.exe 的用法”一节)。

Dllname was loaded, but the DllRegisterServer or DllUnregisterServer entry point was not found.

Dllname不是.dll 或.ocx 文件。例如,键入 regsvr32 wjview.exe 就会生成该错误消息。

例如,键入regsvr32 icwdial.dll 后就会返回该错误消息,因为 Icwdial.dll 文件不能自行注册。如果您怀疑内存中有损坏的Dllname 版本,请尝试重新启动计算机,或重新提取该文件的原始版本。如果您运行的是 Windows NT,可能需要使用 Microsoft Windows NT Server 4.0 资源工具包 中的 Kill 或 Pview 工具。有关其他信息,请单击以查看以下 Microsoft 知识库文章:197155 如何终止孤立进程OleInitialize failed (or OleUninitialize failed).

Regsvr32 必须先初始化 COM 库,然后才能调用所需的 COM 库函数并在关闭时撤消对该库的初始化。

一、轻松修复IE浏览器

regsvr32 Shdocvw.dll

regsvr32 Oleaut32.dll

regsvr32 Actxprxy.dll

regsvr32 Mshtml.dll

regsvr32 Urlmon.dll

regsvr32 browseui.dll

作用:

1、同时运行以上命令不仅可以解决IE不能打开新的窗口,用鼠标点击超链接也没有任何反应的问题;

2、还能解决大大小小的其它IE问题,比如网页显示不完整,JAVA效果不出现,网页不自动跳转,打开某些网站时总提示‘无法显示该页’等。

二、解决Windows无法在线升级的问题

regsvr32 wupdinfo.dll

作用:

Windows的漏洞很多,每隔一段时间就需要使用“Windows Update”升级程序进行在线升级,不过“Windows Update”经常出现无法使用的情况,这时,我们可以使用Regsvr32来解决这个问题。

三、防范网络脚本病毒有新招

regsvr32 /u scrrun.dll

作用:

网络脚本病毒嵌在网页中,上网时在不知不觉中机器就会感染上这种病毒。笔者认为单纯使用杀毒软件并不能有效地防范这些脚本病毒,必须从病毒传播的机理入手。网络脚本病毒的复制、传播都离不开FSO对象(File System Object,文件系统对象),因此禁用FSO对象就能有效地控制脚本病毒的传播。

如果需要使用FSO对象,键入“regsvr32 scrrun.dll”命令即可。

四、卸载Win XP自带的ZIP功能

regsvr32 /u zipfldr.dll

作用:

Win XP以功能强大而著称,但有些功能却常常令人有“鸡肋”之感,比如Win XP自带的ZIP功能和图片预览功能,不仅占用了系统资源,功能也远不如第三方软件强大。其实用Regsvr32命令可以很容易地卸载这些功能。

五、修复无法缩略图查看文件问题

2000: 开始→运行,输入regsvr32 thumbvw.dll

XP: 开始→运行,输入regsvr32 shimgvw.dll

六、让WMP播放器支持RM格式

很多朋友喜欢用Windows Media Player(以下简称WMP)播放器,但是它不支持RM格式,难道非得安装其它播放软件吗?笔者有办法。

以Win XP为例,首先下载一个RM格式插件,解压缩后得到两个文件夹: Release(用于Windows 9x)和Release Unicode (用于Windows 2000/XP);将Release Unicode文件夹下的RealMediaSplitter.ax文件拷贝到“系统盘符\WINDOWS\System32\”目录下;在“开始→运行”中键入“regsvr32 RealMediaSplitter.ax”,点击“确定”即可。接着下载解码器,如Real Alternative,安装后就能用WMP播放RM格式的影音文件了。

七、让WMP9的播放器出现

有些音乐网页的在线点歌需要用到Media Player,有的朋友明明安装了WMP9,但在线听音乐却只看到枯燥的WMP6播放器面板,想让漂亮的WMP9面板出现,当然没问题的。

常见问题的 *** 作系统多数WIN 98,先关闭IE,再在“开始→运行”中键入“regsvr32 wmpdxm.dll”,点击“确定”即可。

八、解决打开系统功能时无反应regsvr32 shdocvw.dll

作用:

有时从开始菜单里点击XP系统的搜索功能、帮助和支持或管理工具等,但就是无任何反应,这是它们的打开方式缺少关联,所以我们只要用regsvr32注册它们需要调用的动态连接库文件就行了。

九、添加/删除程序打不开了regsvr32 appwiz.cpl

regsvr32 mshtml.dll

regsvr32 jscript.dll

regsvr32 msi.dll

regsvr32 "c:\program files\common files\system\ole db\oledb32.dll"

regsvr32 "c:\program files\common files\system\ado\msado15.dll"

regsvr32 mshtmled.dll

regsvr32 /i shdocvw.dll

regsvr32 /i shell32.dll

作用:

当打开控制面板中的添加/删除程序时,双击它的图标后无反应,或者打开后自动关闭了,尝试使用以上命令可以解决。

十、XP的用户帐户打不开regsvr32 nusrmgr.cpl

regsvr32 mshtml.dll

regsvr32 jscript.dll

regsvr32 /i shdocvw.dll

十一、防范网络脚本病毒有新招

regsvr32 /u scrrun.dll 禁用FSO对象

regsvr32 scrrun.dll 使用FSO对象

十二、解决Windows无法在线升级的问题regsvr32 wupdinfo.dll

以下症状我把它称作IE的活动脚本漏洞,虽然这两个命令能修复,但治标不治本,我建议遇到此问题的朋友到微软网站进行IE安全更新,即打漏洞补丁。

regsvr32 jscript.dll

regsvr32 vbscript.dll

作用:

1、跟上面讲的修复IE浏览器方法配合使用(可以不配),可以很好的解决浏览某些网页无法正常显示和功能不正常,如:

a.不显示某些验证码

b.不显示某些动态图片

c.不显示某些论坛的帖子列表

d.论坛快速跳转功能无用

e.论坛发贴时按Ctrl+Enter提交无反应

2、修复个别窗口空白,如XP的‘搜索’功能的搜索助理 *** 作面板空白、系统还原页面空白和用户帐户页面空白等。(可修复把握度100%)

3、解决windows media player 9或以上版本打开时提示‘出现内部应用程序错误’。(可修复把握度100%)

4、可以修复win 2000的‘添加/删除程序’打开后一片空白。(可修复把握度99%)

5、解决win 2000以WEB方式查看Program Files文件夹和Winnt文件夹时看不到任何文件,以及‘控制面板’的图标跑到左边去的问题。

6、解决网页上网际快车的右键菜单功能无法使用。

在网站中,当右键点某个‘下载连接’时,会d出菜单,选择‘使用网际快车下载’会再d出FLASHGET的下载任务页面,如果发现该功能无反应,那就可能是这个原因:原来这项菜单是调用了FLASHGET目录下的jc_link.htm文件,这个文件是用VB语言编写的,所以其作用丢失是动态连接库 vbscript.dll没有注册和调用到。

不过这只是原因之一. 好运 望采纳


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8165470.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-14
下一篇2023-04-14

发表评论

登录后才能评论

评论列表(0条)

    保存