bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 自動更新
查看: 4215|回復: 1
go

自動更新 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2006-5-9 18:38 |只看該作者 |倒序瀏覽 |打印
用Delphi编制可自动升级程序

杨 超

在编制了一个应用程序后的维护阶段,我们会面临给应用程序升级的工作.无疑,手工升级的工作是十分繁琐的,你可能会需要到用户的机器上去更新文件.可是,如果能编一个自动升级程序,放在网络上,让用户下载,只需执行一下就完成升级工作,不是很方便吗?其实,用Delphi可以很方便地编制出这样一个的程序.

以下是我们的例子,设我们已经有一个应用程序This.exe,要对它升级,用来升级的程序为Upgrade.exe.

1.This的工程文件框架
  1. program THIS;

  2. uses SysUtils, Windows, Forms,
  3. ...;
複製代碼
我们将它写入代码中,因为这在Delphi的工程文件中是没有自动生成的.“…”部分是你创建的窗体部分
  1. Var
  2. Fn : String;
  3. TSI : TStartupInfo;
  4. TPI : TProcessInformation;

  5. {$R *.RES}

  6. begin

  7. // “升级程序”使用FileAge来检查原来应用程序的建立时间,如果检测到的是旧版本,则提示升级:

  8. IF FileAge(‘SomeServerSomeDirthis.exe‘) 〉 FileAge(ParamStr(0)) THEN
  9. IF Application.MessageBox(‘这是一个更新版本的THIS.EXE.‘+#13‘你要得到新版本的升级文件吗?‘, ‘Upgrade Time!‘,1) = 1 THEN
  10. Begin

  11. //运行升级程序时,升级程序应与原主程序this.exe在同一目录下.
  12. //如果当它启动时,这个版本主程序应该退出,但要保证它不会删除任何文件,因为此时Application.Initialize还没有被调用.代码如下:

  13. Fn := ExtractFilePath(ParamStr(0))+‘UpgradeThis.exe‘;
  14. FillChar(TSI, SizeOf(TSI), 0);
  15. TSI.CB := SizeOf(TSI);
  16. IF CreateProcess (PChar(Fn), NIL, NIL, NIL, False, DETACHED_PROCESS, NIL, NIL, TSI, TPI)
  17. THEN Exit

  18. //但是,如果“升级程序”由于某些原因没有运行,我们此时应该告诉用户,他能通过其他方法得到一个更新的程序版本,这时我们依然退出主程序以便用户升级.如果必要的话,也可以继续装入并运行旧版本.

  19. ELSE
  20. Begin

  21. MessageBeep(0);
  22. Application.MessageBox(‘不能完成文件拷贝.‘+‘ ‘ 请手工拷贝!.‘, ‘Copy Error!‘,1);
  23. Exit;

  24. End;

  25. End;

  26. Application.Initialize;
  27. Application.Title := ‘This‘;
  28. Application.HelpFile := ‘This.hlp‘;
  29. {autocreate forms, etc.}
  30. Application.Run;

  31. end.
複製代碼
如果自动升级程序是一个控制台程序,那么一定要保证正确的控制台程序连接选项设置.
  1. program UpgradeThis;

  2. uses Forms, SysUtils, Windows;

  3. Var

  4. Fn : String;
  5. TSI : TStartupInfo;
  6. TPI : TProcessInformation;

  7. {$R *.RES}

  8. begin

  9. //用CopyFile来拷贝新版本的文件,同FileAge一样,它不考虑标准命名格式的路径和文件名.

  10. IF CopyFile(‘SomeServerSomeDirthis.exe‘, PChar(ExtractFilePath(ParamStr(0))+‘this.exe‘),False) THEN
  11. Begin

  12. //一旦这些新版本的文件被拷贝到系统中,它就应该能够运行了,而且也没有理由不运行.所以,这里基本上不需要加入出错检测的代码.
  13. //那么,例子中使它运行并简单处理错误的代码如下:

  14. Fn := ExtractFilePath(ParamStr(0))+‘this.exe‘;
  15. FillChar(TSI, SizeOf(TSI), 0);
  16. TSI.CB := SizeOf(TSI);
  17. CreateProcess(PChar(Fn), NIL, NIL, NIL, False, DETACHED—PROCESS, NIL, NIL, TSI, TPI);
  18. End

  19. ELSE
  20.   Application.MessageBox(‘不能拷贝文件THIS.EXE‘, ‘Error!‘, mb_OK);
  21. end.
複製代碼
需要注意的是,在这些用来升级程序的代码中,并没有用到任何Application.Initialize和Application.Run.这些方法同样可以被引用来作检查新版本的帮助文件(用GetWindowsDir或GetWindowsDirectory并把“Help”加入到用来升级的程序中)或用来检测“升级程序”是否是新的版本.

上面只是从文件的更新角度说明了编制“升级程序”的方法,但在很多情况中升级一个程序甚至要修改注册表或各种INI的文件,这些在Delphi中是比较容易实现的,有兴趣的朋友可以参照一些资料来加入实现这些功能的代码.
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw

Rank: 9Rank: 9Rank: 9

2#
發表於 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
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-4-30 18:15 , Processed in 0.017038 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.