软件框架做成插件模式。 不是插件也行。 系统本地有更新版本记录。 网上有个最新版本列表,每次到指定网页对比, 更新程序最好做成单独的,每次更新时启动更新 程序。 用覆盖就可以, 如果是一个exe的, 比较死板,这样可以用下面代码更新。
unit uautoupdate;
//this unit is used to auto download and replace a .exe or .dll file
//just call TAutoUpdate.create(hinstance,info_url,cversion)
//hinstance: the module you want to replace
//info_url: an http or ftp url which contain the information of an new version
// the format is: version=... <CR> url=...<CR> filesize=... <CR>
//cversion: current version of the file
interface
uses
Classes,Windows,Urlmon,sysutils,Inifiles,WinINet;
type
TAutoUpdate = class(TThread)
private
finfo_url,fversion,ffilename:string;
protected
procedure Execute; override;
public
constructor create(hinstance:thandle;info_url,cversion:string);
end;
implementation
function HTTPRequest(const URL:String):string;
var
HFile,HInet: HINTERNET;
Buffer : array[0..32767] of char;
BufRead : Cardinal;
BufSize:Cardinal;
const
Agent = 'Netbar';
begin
HInet := InternetOpen(Agent,INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
result:='';
if Assigned(HInet) then
try
HFile := InternetOpenUrl(HInet, PChar(URL), nil, 0, INTERNET_FLAG_RELOAD+INTERNET_FLAG_KEEP_CONNECTION, 0);
if Assigned(HFile) then
try
BufSize:=SizeOf(Buffer);
while InternetReadFile(HFile, @Buffer, BufSize, BufRead) and (BufRead > 0) do
begin
Buffer[BufRead]:=#0;
result:=result+PChar(@Buffer);
end;
finally
InternetCloseHandle(HFile);
end;
finally
InternetCloseHandle(hinet);
end;
end;
procedure MoveFile(src,dst:string);
var MyIni: TIniFile;
begin
if GetVersion<$80000000 then // Windows NT/2000/XP
begin
MoveFileEx(Pchar(src),Pchar(dst),MOVEFILE_DELAY_UNTIL_REBOOT);
end else
begin // Windows 32s/95/98/Me
MyIni := TIniFile.Create('WININIT.INI');
Myini.WriteString('rename',ExtractShortPathName(dst),ExtractShortPathName(src));
MyIni.free;
end;
end;
constructor TAutoUpdate.create(hinstance:thandle;info_url,cversion:string);
var
filename:array[0..MAX_Path] of char;
begin
finfo_url:=info_url;
fversion:=cversion;
getmodulefilename(hinstance,filename,sizeof(filename));
ffilename:=strpas(filename);
inherited create(false);
end;
function Get_FileSize(FileName : String) : Integer;
var
F : THandle;
fSize : DWORD;
begin
//Open up file
F := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR FILE_FLAG_NO_BUFFERING, 0);
fSize := GetFileSize(F, nil); //Get the file's size
CloseHandle(F);
Result :=fsize;
end;
procedure TAutoUpdate.Execute;
var
info:string;
param:TStringList;
newversion,url:string;
begin
info:=httprequest(finfo_url);
param:=TStringlist.Create;
param.Text:=info;
newversion:=param.Values['version'];
if newversion<=fversion then exit;
url:=param.values['url'];
if S_OK<>urldownloadtofile(nil,pchar(url),pchar(ffilename+'.tmp'),0,nil) then exit;
if inttostr(Get_FileSize(ffilename+'.tmp'))<>param.values['filesize'] then exit;
MoveFile(ffilename+'.tmp',ffilename);
end;
end.