程序自动升级问题(100分)

  • 主题发起人 主题发起人 SiWeiLiuLang
  • 开始时间 开始时间
S

SiWeiLiuLang

Unregistered / Unconfirmed
GUEST, unregistred user!
C/S的程序,加入了一个自动升级功能,当发现版本更新时,自动下载程序并安装。<br>执行如下:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShellExecute(Handle,'open',PChar('HRSetup.exe'),nil,nil,SW_SHOW);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application.Terminate;<br>问题时,程序结束需要花费一定时间,虽然做了等待的提示,但往往用户安装失败,造成了一定的麻烦。<br>请问,有没有什么技巧,可以避免这样的问题。
 
可以判有新版本后先自行下载升级程序到本地,下载完毕后再给用户一个提示,用户确定后自动关闭其程序,判断其程序已经关闭后,把下载的文件覆盖上去,再启动。。。
 
你可以考虑只升级主程序,其实完全没有必要每次升级都要重新安装,一般是更新主程序的可执行文件就可以了。覆盖掉原来地旧文件后再运行就没有那么多麻烦了,我就是这样处理的,一直很稳定。
 
在升级的程序中waitforsingleObject等待主程序的结束.<br>或者贼升级程序中把主程序改名或者移到备份目录.<br>Windows的程序在执行的时候是可以改名和移动的.
 
我的方法与 szhcracker 类似<br>先将升级的文件下载到临时目录下,关闭应用程序,删除当前目录下需升级的文件(作个循环判断,只要还存在就一直删下去),再拷贝临时文件目录下的文件到当前目录,一直这么用没出过错。
 
看瑞星,他做的就是由主程序检查是否有更新,如果有的话,则去启动更新程序去下载新的应用,下载完后,其关掉主程序,然后再将原程序是覆盖还是装载的启动起来。
 
我想问问的是,更新的方式是使用FTP方式还是UDP方式更新?
 
这个问题我已经解决了,就是用专业的自动升级组件:AutoUpdate+,有源码,非常方便,唯一需要就是在主机上安装一个HTTP的服务,我用的是免费的HFS 2.3版。强烈推荐你用这个方法。几乎不用额外的代码,只在软件启动时用一行语句让组件连到HTTP服务检测一下有没有新版就OK了,如果有组件会自动下载并覆盖原文件,并自动重新启动软件。
 
楼上朋友,AutoUpdate+有没有2.5x的?
 
自己写个更好用
 
KeyLife富翁笔记 &nbsp;<br>作者?: 曾经<br>标题?: 编写通用的程序更新模块 <br>关键字: <br>分类?: 个人专区 <br>密级?: 公开 <br>(评分: , 回复: 0, 阅读: 114) ?? <br>目前,大多数商业软件都提供一种“在线升级”的功能,用户只需上网点几下鼠标即可完成程序的更新升级。笔者所在的单位拥有一个连接了上百台计算机的局域网,上面运行着一套信息管理系统。为解决客户端应用程序的更新升级,笔者编制了一个实现自动更新功能的模块。该模块能在不同的编程语言中实现升级功能,具有一定的通用性和灵活性。本文介绍该模块(PiUpdate)的设计思路和实现方法。 <br><br>实现原理 <br>PiUpdate模块的基本设计思想是将要更新的文件放在文件服务器上,工作站上的程序启动时调用PiUpdate, 对比服务器上的文件和本地的文件,如发现有新文件,则更新本地的对应文件。 <br>首先,考虑到通用性的要求,将该模块设计成一个Windows标准的动态链接库(DLL),并在DLL中提供一个接口函数供其他程序调用。由于几乎各种开发工具都支持DLL调用机制,这样就保证了模块的通用性。 <br>其次,为了灵活控制具体的更新文件,笔者使用了一个ini文件来提供相关的更新信息。ini文件名在主程序调用DLL接口函数时传入程序。 <br>接口函数的定义形式如下: <br>function ExecuteUpdate(IniFileName:Pchar):integer; stdcall; <br>如果更新成功,则返回0,如果出现错误,则返回-1; 当将要更新的文件被运行中的应用程序使用时,接口函数会向主程序返回1。 软件开发网 www.mscto.com <br>接口函数的调用形式如下: <br>Delphi调用:function ExecuteUpdate(inifilename:pchar):integer;stdcall;external ‘PiUpdate.dll’; <br>PB调用:function integer ExecuteUpdate(ref string name) library“PiUpdate.dll” <br>考虑到不同编程语言中字符串存储形式不尽相同,函数参数采用了Windows API标准的C语言字符串形式,并且调用形式也采用Windows标准的StdCall形式。 <br>配置ini文件的形式如下: <br>[程序名称] <br>filename1=//Server/Share/filename1 <br>filename2=//Server/Share/filename2 <br>… <br>更新方法 <br>本文在更新一般文件时,使用的是CopyFile API。对于正在使用的文件,这个方法就行不通了。开始时,笔者查找了Windows API的有关资料,发现MoveFileEx函数可以在Windows重新启动时更新指定文件,这可以作为一种更新正在使用的文件的方法。但如果只是更新一个小程序,就要用户重新启动,有点小题大做的味道。后来,笔者在网上看到HAPPYZSL的一篇文章,发现其中使用的技巧十分有效。更新过程的思路是:如果发现被更新的文件正在使用,则将源文件复制到本地的一个临时文件,并建立一个del.BAT文件。在程序结束时运行该BAT文件,以完成对这些正在使用的文件的更新。del.BAT文件的内容如下: <br>@echo off <br>: loop <br>del destfile <br>if exist destfile goto loop <br>copy tmpfile destfile <br>del tmpfile <br>del ./del.bat <br>由于del.BAT运行后会一直执行,直到成功地删除了目标文件为止,所以主程序在检测到接口函数ExecuteUpdate返回值为1时,要立即退出,以便del.BAT能顺利地执行下去。 <br>程序实现 <br>主程序的实现代码如下: <br>function ExecuteUpdate(IniFileName: Pchar):integer; <br>//返回值:0 更新成功;-1 更新出错; 1 要更新的文件正在使用,需要立即退出程序 <br>begin <br>result: =-1 ; <br>//获取配置文件名称 <br>FName: =StrPas(IniFileName); <br>ProgList: =TStringList.Create; <br>try <br>//初始化更新配置信息 <br>if InitUpdate(FName) then <br>begin <br>UpdateList:=TStringList.Create; <br>try <br>//检查需要更新的文件 <br>if CheckNeedUpdate(ProgList, <br>UpdateList) then <br>//执行更新操作 <br>result: =DoUpdate(UpdateList) <br>else <br>result: =0; <br>finally <br>UpdateList.Free; <br>end; <br>end; <br>finally <br>ProgList.Free; <br>end; <br>end; <br>小 结 <br>如果在建立ini文件时,没有指定文件的目录位置,则默认使用Windows的系统目录,所以在调用接口函数时最好用ini文件的全路径名称。如果不方便给出全路径名称,也可以采用“./filename.ini”的形式进行调用。 <br>对于文件是否需要更新,程序员可以根据实际情况来编写判断标准。为方便修改,在程序中将其写成函数FileDiff(sFile,dFile: string)的形式,可以加上文件大小、版本号等条件。 <br>为了使更新过程能更加完善,建议将本模块及更新配置文件也放在服务器上相应的共享目录下,并作为待更新的文件加到更新文件列表中。这样一来,如果服务器端的PiUpdate.dll更新了,用户的PiUpdate.dll也会同样得到更新。如果由于程序功能的增加,加入了新的文件,只要将新加的文件放到服务器上,并修改服务器上的更新配置文件,工作站上的程序启动时会先将新的配置文件复制到本地,下次本地程序再启动时就可以更新新加入的文件。
 
后退
顶部