浅议Delphi程序如何实现自动升级

时间:2022-03-17 06:41:24

浅议Delphi程序如何实现自动升级

摘要:用C/S结构开发的网络软件,要解决的主要问题之一就是客户端的自动升级,只有完成了这一功能,才能使开发的网络软件能及时更新与完善。在delphi中,通过对比当前版本和最新版本的客户端程序的修改时间来决定是否升级客户端,利用Delphi的TIdTCPClient,TIdUDPServer,TIdTCPServer,TIdUDPClient等网络通讯控件来完成客户端程序的的传输与升级。

关键词:自动升级;基本原理;客户端;服务器

中图分类号:TP311文献标识码:A 文章编号:1009-3044(2008)09-11662-04

How Discusses the Delphi Procedure to Realize the Automatic Promotion Shallowly

FU Xin-juan

(Victory petroleum administrative bureau victory hospital informationcenter microcomputer room,Dongying 257055 China)

Abstract: With the C/S structure development's network software, one which of subject matters must solve is the client side automatic promotion, only then has completed this function, can enable the development the network software to renew and the consummation promptly. In Delphi, through the contrast current edition and the newest edition's client side procedure's revision time decided whether to promote the client side, uses Delphi TIdTCPClient, TIdUDPServer, TIdTCPServer, network communications and so on TIdUDPClient controls completes the client side procedure the transmission and the promotion.

Key words: Automatic promotion; Basic principle; Client side; Server

1 引言

现在的许多网络软件都实现了自动升级功能,从各种杀毒软件,到QQ、UC这样的即时通讯软件,都有这方面的功能。这一功能的实现可以使程序不用人工干预,自动完成程序的升级与更新。在开发网上办公系统的过程中,由于采用C/S结构,客户端经常需要更新,通过对这些网络软件的分析,掌握了软件自动升级的基本原理,在Delphi中轻松得以实现。

2 实现的基本原理

自动升级的实现需要由客户端和服务器两部分来完成,客户端在启动时,先判断本地升级目录中的客户端程序的修改时间是否和正在运行的客户端程序的修改时间一致,如果不一致,就运行升级程序完成升级。客户端运行后定时检测服务器,如果有新程序,就下载到本地升级目录中,等待下次启动时完成升级。

3 具体的实现方法

客户端在运行后,就动态检测服务器端应用程序的情况,一发现有新的客户端程序,就及时下载升级。

3.1 客户端的实现代码

(1)在Delphi中新建客户应用程序,在其工程文件中判断当前程序是否和升级目录程序的修改时间一致,若是不一致,就运行客户端升级程序upgrade.exe。

msgclient.dpr中的核心代码:

program msgclient;

uses

……

{$R *.RES}

Var

upfilename,newfilename,filename:string;

upfiletime,newfiletime:integer;

begin

……

//如果升级目录upgrade中有最新版本的客户端程序,则启动软件升级程序upgrade.exe,并退出。

upfiletime :=0;

newfiletime :=0;

upfilename:=ExtractFilePath(paramstr(0))+'upgrade\netoffice.exe' ;

newfilename:=ExtractFilePath(paramstr(0))+'netoffice.exe';

if fileexists(upfilename) then

upfiletime:=fileage(upfilename);

newfiletime:=fileage(newfilename);

filename:=ExtractFilePath(paramstr(0))+'upgrade.exe';

if (upfiletimenewfiletime) and (upfiletime0) then

begin

winexec(pchar(filename),SW_SHOWNORMAL);

exit;

end;

……

end.

(2)新建应用,命名为upgrade,用于升级本地客户端程序,在工程文件upgrade.dpr中用函数FindWindow(nil,'NetOffice_Fxj')获得客户端程序的主窗口句柄,再判断升级目录中是否有升级后的客户端软件,若存在就用函数SendMessage(WsbgHWnd,WM_CLOSE,0,0)关闭客户端程序,用函数copyfile(pchar(upfilename),pchar(newfilename),False)把升级目录中客户端程序复制到当前目录并运行。

关键代码:

program upgrade;

uses

……

{$R *.RES}

Var

WsbgHWnd : HWnd;

upfilename,newfilename:string;

begin

//获得当前客户端程序的文件句柄。

WsbgHWnd := FindWindow(nil,'NetOffice_Fxj');

upfilename:=ExtractFilePath(paramstr(0))+'upgrade\netoffice.exe' ;

newfilename:=ExtractFilePath(paramstr(0))+'netoffice.exe';

if fileexists(upfilename) then

begin

if WsbgHWnd 0 then

begin

SendMessage(WsbgHWnd ,WM_CLOSE,0,0);

end;

deletefile(newfilename);

Application.MessageBox('系统已更新。','信息',MB_OK+MB_ICONINFORMATION);

copyfile(pchar(upfilename),pchar(newfilename),False);

WinExec(pchar(newfilename),SW_SHOWNORMAL);

exit;

end;

application.Terminate;

Application.Initialize;

Application.Run;

end.

(3)客户端软件在启动时向服务器端发送升级检测命令,及本地客户端的修改时间,服务器端在收到信息后和服务器端升级目录中的客户端程序的修改时间作对比,若不一致,就发送升级后的客户端程序。

在客户端程序的主窗体中加入TIdTCPServer控件和TIdUDPServer控件。在TIdUDPServer控件的OnUDPRead事件中加入如下代码,用全局变量upgradetime获得升级后客户端程序的修改时间。

{rec:TString变量,接收服务器发送的信息。}

if rec.Values['cmd']='upgrade' then

begin

upgradetime:=strtoint(rec.Values['upfiletime']);

end;

在TIdTCPServer控件的OnExecute事件中加入如下代码,用于接收服务器端发送的最新版本的客户端程序:

procedure TFrm_main.TCPServerExecute(AThread: TIdPeerThread);

var

MYFStream:TFileStream;

filename,ssr:string;

newfile:integer;

sr: TSearchRec;

begin

//接收服务器端发来的信息。

filename:=AThread.Connection.ReadLn;

if filename'' then

begin

filename:=extractfilepath(paramstr(0)) + filename;

ssr:=extractfilepath(filename);

StrLCopy(Pchar(ssr),pchar(ssr),Length(ssr)-1);

if FindFirst(ssr, faDirectory, sr) 0 then

MkDir (extractfilepath(filename));

MyFStream := TFileStream.Create(filename, fmCreate);

Try

AThread.Connection.ReadStream(MyFStream,-1,True);

finally

AThread.Connection.Disconnect;

MYFStream.Free;

FindClose(sr);

end;

if upgradetime0 then

begin

newfile:=FileOpen(filename,fmOpenWrite);

FileSetDate(newfile,upgradetime);

FileClose(newfile);

upgradetime:=0;

end;

end;

end;

3.2 服务器端的实现代码

服务器端在收到客户端发送的升级检测命令及客户端程序的修改时间后,把收到的客户端程序的修改时间和服务器端升级目录中的修改时间作对比,如果不一致,就把升级目录中的客户端程序发送到客户端。

在服务器的主窗体中加入TIdTCPClient控件和TIdUDPServer控件,在TIdUDPServer控件的OnUDPRead事件中加入如下代码完成这一功能。

{ rec:TString变量,接收客户端发送的信息,若接收到的信息为“upgrade”,则执行升级代码。}

if rec.Values['cmd']='upgrade' then

begin

//服务器端的升级目录中有最新版的客户端程序时,把它发送到客户端。

if FileExists(ExtractFilePath(paramstr(0))+'upgrade\netoffice.exe') then

begin

newfiletime:=FileAge(ExtractFilePath(paramstr(0))+'upgrade\netoffice.exe');

if inttostr(newfiletime)rec.Values['upfiletime'] then

begin

newfilename:='upgrade\netoffice.exe';

TCPClient.Host:=ABinding.PeerIP;

Try

TCPClient.Connect;

TCPClient.Writeln(newfilename);

newfilename:=extractfilepath(paramstr(0))+newfilename;

Fm := TfileStream.Create(newfilename,fmsharedenywrite);

TCPClient.OpenWriteBuffer;

TCPClient.WriteStream(Fm);

TCPClient.CloseWriteBuffer;

Finally

TCPClient.Disconnect;

Fm.Free;

End;

rec.Values['upfiletime']:=inttostr(newfiletime);

TmpStr := rec.text;

Binding.SendTo(ABinding.PeerIP,RemoteUDPport,TmpStr[1],length(TmpStr));

end;

end;

end;

4 结束语

这里只简单介绍了完成软件自动升级的基本方法和实现的核心代码,在自己的软件中可以进行扩充和完善。只要细心研究,许多商业软件能完成的功能,也能在自己开发的软件中实现。

参考文献:

[1] 肖建.Delphi 6编程基础[M].北京:清华大学出版社,2001.

[2] 曹智威.Delphi6实用编程技术[M]. 北京: 水利水电出版社,2002.

[3] 黄建华.Delphi程序设计[M].清华大学出版社,北京,1997.

上一篇:基于J2EE架构的办公自动化系统的分析与设计 下一篇:基于SOA的校园信息系统集成研究