bestlong 怕失憶論壇
標題:
自動更新
[打印本頁]
作者:
bestlong
時間:
2006-5-9 18:38
標題:
自動更新
用Delphi编制可自动升级程序
杨 超
在编制了一个应用程序后的维护阶段,我们会面临给应用程序升级的工作.无疑,手工升级的工作是十分繁琐的,你可能会需要到用户的机器上去更新文件.可是,如果能编一个自动升级程序,放在网络上,让用户下载,只需执行一下就完成升级工作,不是很方便吗?其实,用Delphi可以很方便地编制出这样一个的程序.
以下是我们的例子,设我们已经有一个应用程序This.exe,要对它升级,用来升级的程序为Upgrade.exe.
1.This的工程文件框架
program THIS;
uses SysUtils, Windows, Forms,
...;
複製代碼
我们将它写入代码中,因为这在Delphi的工程文件中是没有自动生成的.“…”部分是你创建的窗体部分
Var
Fn : String;
TSI : TStartupInfo;
TPI : TProcessInformation;
{$R *.RES}
begin
// “升级程序”使用FileAge来检查原来应用程序的建立时间,如果检测到的是旧版本,则提示升级:
IF FileAge(‘SomeServerSomeDirthis.exe‘) 〉 FileAge(ParamStr(0)) THEN
IF Application.MessageBox(‘这是一个更新版本的THIS.EXE.‘+#13‘你要得到新版本的升级文件吗?‘, ‘Upgrade Time!‘,1) = 1 THEN
Begin
//运行升级程序时,升级程序应与原主程序this.exe在同一目录下.
//如果当它启动时,这个版本主程序应该退出,但要保证它不会删除任何文件,因为此时Application.Initialize还没有被调用.代码如下:
Fn := ExtractFilePath(ParamStr(0))+‘UpgradeThis.exe‘;
FillChar(TSI, SizeOf(TSI), 0);
TSI.CB := SizeOf(TSI);
IF CreateProcess (PChar(Fn), NIL, NIL, NIL, False, DETACHED_PROCESS, NIL, NIL, TSI, TPI)
THEN Exit
//但是,如果“升级程序”由于某些原因没有运行,我们此时应该告诉用户,他能通过其他方法得到一个更新的程序版本,这时我们依然退出主程序以便用户升级.如果必要的话,也可以继续装入并运行旧版本.
ELSE
Begin
MessageBeep(0);
Application.MessageBox(‘不能完成文件拷贝.‘+‘ ‘ 请手工拷贝!.‘, ‘Copy Error!‘,1);
Exit;
End;
End;
Application.Initialize;
Application.Title := ‘This‘;
Application.HelpFile := ‘This.hlp‘;
{autocreate forms, etc.}
Application.Run;
end.
複製代碼
如果自动升级程序是一个控制台程序,那么一定要保证正确的控制台程序连接选项设置.
program UpgradeThis;
uses Forms, SysUtils, Windows;
Var
Fn : String;
TSI : TStartupInfo;
TPI : TProcessInformation;
{$R *.RES}
begin
//用CopyFile来拷贝新版本的文件,同FileAge一样,它不考虑标准命名格式的路径和文件名.
IF CopyFile(‘SomeServerSomeDirthis.exe‘, PChar(ExtractFilePath(ParamStr(0))+‘this.exe‘),False) THEN
Begin
//一旦这些新版本的文件被拷贝到系统中,它就应该能够运行了,而且也没有理由不运行.所以,这里基本上不需要加入出错检测的代码.
//那么,例子中使它运行并简单处理错误的代码如下:
Fn := ExtractFilePath(ParamStr(0))+‘this.exe‘;
FillChar(TSI, SizeOf(TSI), 0);
TSI.CB := SizeOf(TSI);
CreateProcess(PChar(Fn), NIL, NIL, NIL, False, DETACHED—PROCESS, NIL, NIL, TSI, TPI);
End
ELSE
Application.MessageBox(‘不能拷贝文件THIS.EXE‘, ‘Error!‘, mb_OK);
end.
複製代碼
需要注意的是,在这些用来升级程序的代码中,并没有用到任何Application.Initialize和Application.Run.这些方法同样可以被引用来作检查新版本的帮助文件(用GetWindowsDir或GetWindowsDirectory并把“Help”加入到用来升级的程序中)或用来检测“升级程序”是否是新的版本.
上面只是从文件的更新角度说明了编制“升级程序”的方法,但在很多情况中升级一个程序甚至要修改注册表或各种INI的文件,这些在Delphi中是比较容易实现的,有兴趣的朋友可以参照一些资料来加入实现这些功能的代码.
作者:
bestlong
時間:
2006-5-9 18:41
用过一般的杀毒软件,都知道,启动程序时,常会问,网上已经有新版本的,是否升级之类的提示,现在越来越多的软件都支持在线升级,你是否也想实现这个功能?本文就是如何实现在线升级,讲述一下如何通过HTTP检测是否需要下载升级版本,并下载升级。
[ 相关贴图 ]
[ 相关贴图 ]
[ 相关贴图 ]
实现步骤:
1、网站提供升级信息。
2、使用HTTP从网站下载升级信息。
3、确定是否进行升级
4、升级程序
下面我们定义一下升级信息:
[文件名1]
datetime=时间
[文件名2]
datetime=时间
存为HTML文件,如定义一个update.htm
[programe1.exe]
datetime=2003-07-06
[programe1.hlp]
datetime=2003-07-06
这里只是简单的判断一下文件的时间,如果时间比需要升级的文件时间小的,表示要下载新版本升级它。当然要做到十全十美,这是判断是不合理的,这里只作个简单的介绍。
写个fuction,判断是否有新的版本要升级
function ExistNewfile&:boolean;
var i, iFileHandle: integer;
FileDateTime: TDateTime;
AppIni:TiniFile;
g_path:string;
url:string;
files:TStrings;
begin
result := false;
url := 'http://yousoft.hi.com.cn/update.htm'; //要升级的服务器
g_path := ExtractFilePath(application.ExeName); //升级程序的路径
if copy(g_path, length(g_path), 1) <> '' then g_path := g_path + '';
if copy(url, length(url),1 ) <> '/' then url := url + '/';
//下载升级信息文件
try
HTTPFiles.InputFileMode := true;
HTTPFiles.OutputFileMode := FALSE;
HTTPFiles.ReportLevel := Status_Basic;
HTTPFiles.Body := g_path + 'update/update.ini'; //下载后保存到程序的update目录下
HTTPFiles.Get(url);
except
result := false; //取得升级信息出错!,不用再继续
exit;
end;
try
files:=TStringlist.Create; //有哪些文件?
AppIni := TIniFile.Create(g_path+‘updateupdate.ini‘);
AppIni.ReadSections(files);
for i := 0 to files.Count - 1 do
try
iFileHandle :=FileOpen(g_path + files
, fmShareDenyNone);
FileDateTime := FileDateToDateTime(FileGetDate(iFileHandle)); //取得文件时间
FileClose(iFileHandle);
//是否要下载文件
if FileDateTime < StrToDatetime(AppIni.ReadString(files
, 'datetime', '1900-1-1')) then
begin
result := true;
break;
end;
except
end;
finally
AppIni.free;
files.Free;
end;
end;
取得files后文件下载!httpfiles为TNMHTTP
HTTPFiles.InputFileMode := true;
HTTPFiles.OutputFileMode := FALSE;
HTTPFiles.ReportLevel := Status_Basic;
HTTPFiles.Body := g_path + 'update/' + files
;
HTTPFiles.Get(url);
把下载后的文件复制到原程序,并备份出一份
for i:=0 to files.Count-1 do //备份文件
begin
//备份一份文件出来
copyfile(pchar(g_path+files
),pchar(g_path+files
+‘.bak‘),false);
end;
for i:=0 to files.Count-1 do //从update复制新文件
begin
copyfile(pchar(g_path+‘update‘+files
),pchar(g_path+files
),false);
end;
因为采用了TNMHTTP,文件下载的进度并不是很好控制,可以在TNMHTTP的PacketRecvd事件,确定进度
在线升级的方法就这样简单介绍了,在DELPHI6+WIN2000环境调试通过,这里我没有写出完整的代码,有兴趣可以自己写写,多加改善
在我的主页我做了演示程序,大家可以看看,网址是:
http://yousoft.hi.com.cn
歡迎光臨 bestlong 怕失憶論壇 (http://www.bestlong.idv.tw/)
Powered by Discuz! X1.5