关于自动更新的下载部分

发布时间:2008-7-31 9:22:55文章来源:编程中国浏览次数:
选择您适合观看的字体大小:  
原帖及讨论:http://bbs.bc-cn.net/dispbbs.asp?BoardID=9&ID=179765 

*/ -------------------------------------------------------------------------------------- 
*/ 出自: 编程中国  http://www.bc-cn.net 
*/ 作者: anthony634         
*/ 时间: 2007-10-22  编程论坛首发 
*/ 声明: 尊重作者劳动,转载请保留本段文字 
*/ -------------------------------------------------------------------------------------- 




上周有位本论坛的朋友在QQ里问到传奇私服的自动更新的问题,当时在网吧打游戏随便回答了一些问题,今天早上刚好有空,抽了些时间,写了段demo,其实如果下载了indy,它是自带有demo 的,这里用到了线程和地址重定向,算是一个简单的实例吧,由于时间仓促,封装和命名上就马虎了。注析也不详细。 
下载文件是http://www.bc-cn.net/Soft/kfyy/delphi/edu/200604/296.html 
界面部分: 


Unit Unit1; 

interface 

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, Unit2, ComCtrls, StdCtrls, ExtCtrls; 
type 
  TForm1 = class(TForm) 
    Button1: TButton; 
    ProgressBar1: TProgressBar; 
    Button2: TButton; 
    Button3: TButton; 
    Memo1: TMemo; 
    Button4: TButton; 
    Edit1: TEdit; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
    procedure FormShow(Sender: TObject); 
  private 
    { Private declarations } 
    fWeb: string; 
    fDownLoadThread: TDownLoadThread; 
  public 
    { Public declarations } 
    procedure OnShowProgress(DownCount: Integer); 
    procedure OnGetFileSize(fileSize: Integer); 
    procedure OnShowStatus(aString: string); 
  end; 

var 
  Form1: TForm1; 

implementation 

{$R *.dfm} 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  fDownLoadThread := TDownLoadThread.Create(True); 
  fDownLoadThread.FreeOnTerminate := True; 
  fDownLoadThread.OnDownLoadCount := OnShowProgress; 
  fDownLoadThread.OnShowString := OnShowStatus; 
  fDownLoadThread.OnGetFileSize := OnGetFileSize; 
  fDownLoadThread.initDownLoad(fWeb); 
  fDownLoadThread.Resume(); 
end; 

procedure TForm1.OnShowProgress(DownCount: Integer); 
begin 
  if DownCount > ProgressBar1.Max then 
    Exit 
  else 
    ProgressBar1.Position := DownCount; 
end; 

procedure TForm1.OnGetFileSize(fileSize: Integer); 
begin 
  ProgressBar1.Position := 0; 
  ProgressBar1.Max := fileSize; 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
begin 
  fDownLoadThread.Terminate(); 
end; 

procedure TForm1.Button3Click(Sender: TObject); 
begin 
  fDownLoadThread.Suspend(); 
end; 

procedure TForm1.OnShowStatus(aString: string); 
begin 
  Memo1.Lines.Add(aString); 
end; 

procedure TForm1.FormShow(Sender: TObject); 
begin 
  // 页面是 http://www.bc-cn.net/Soft/kfyy/delphi/edu/200604/296.html 
  fWeb := ’http://www.bc-cn.net/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296’; 
  Edit1.Text := ’目标地址:’ + fWeb; 
end; 

end. 


下载线程部分 

unit Unit2; 

interface 

uses 
  Classes, SysUtils, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, 
  IdHTTP, IdFTP; 

type 
  TOnDownLoadCount = procedure(DownCount: Integer) of object; 
  TOnShowString = procedure(aString: string) of object; 
  TDownLoadThread = class(TThread) 
  private 
    { Private declarations } 
    fDestFileName: string; 
    fFileSize: Integer; 
    FDestWebAddr: string; 
    fIdHttp: TIdHTTP; 
    fIdFtp: TIdFTP; 
    fDownLoadItem: TFileStream; 
    fOnDownLoadCount: TOnDownLoadCount; 
    fOnShowString: TOnShowString; 
    fOnGetFileSize: TOnDownLoadCount; 
    procedure OnDownLoadWork(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCount: Integer); 
    procedure OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCountMax: Integer); 
    procedure OnStatus(axSender: TObject; const axStatus: TIdStatus; 
  const asStatusText: String); 
    procedure OnRedirect(Sender: TObject; var dest: String; 
  var NumRedirect: Integer; var Handled: Boolean); 
  protected 
    procedure Execute; override; 
  public 
    constructor Create(CreateSuspended: Boolean); 
    destructor Destroy(); override; 
    procedure initDownLoad(aWeb: string); 
    property OnDownLoadCount: TOnDownLoadCount write fOnDownLoadCount; 
    property OnShowString: TOnShowString write fOnShowString; 
    property OnGetFileSize: TOnDownLoadCount write fOnGetFileSize; 
  end; 

implementation 
{ TDownLoadThread } 

procedure TDownLoadThread.Execute; 
begin 
  { Place thread code here } 
  try 
    fIdHttp.Connect(); 
    fIdHttp.Head(’/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296’); 
  except 
    if FDestWebAddr <> ’’ then 
      fOnShowString(’地址重定向到:’ + FDestWebAddr) 
    else 
      fOnShowString(’连接失败.’); 
  end; 

  // 这里这里应该分析重定向后的地址FDestWebAddr,根据地址决定是http下载还是ftp下载 这里省略了。 
  // 得到的地址是:ftp://down1:008@down1.bc-cn.net/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar 
  // 分析地址应该使用ftp,并得到一下信息 
  fIdFtp := TIdFTP.Create(nil); 
  fIdFtp.User := ’down1’;  // 用户名 
  fIdFtp.Password := ’008’; // 密码 
  fIdFtp.Host := ’down1.bc-cn.net’; // 主机 
  fIdFtp.Port := 21;        // 端口,可以不设,默认就是21的 ,这里用的是端口模式。 
  fIdFtp.OnWork := Self.OnDownLoadWork; // 实现相应的事件,这是下载过程 
  fIdFtp.OnWorkBegin := Self.OnWorkBegin;  // 下载开始 
  fIdFtp.OnStatus := Self.OnStatus; 
  fIdFtp.Connect(); 
  fFileSize := fIdFtp.Size(’/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar’); 
  fOnShowString(’文件大小: ’ + IntToStr(fFileSize)); 
  fIdFtp.Get(’/down1_18/1_kfyy/5_delphi/edu/delphi7_zjjfbsyykf.rar’, fDownLoadItem); 
end; 

procedure TDownLoadThread.OnDownLoadWork(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCount: Integer); 
begin 
  if Self.Terminated then 
  begin 
    try 
      TIdTCPConnection(Sender).DisconnectSocket(); 
    except 
      fOnShowString(’ DisconnectSocket’); 
    end; 
  end; 
  fOnDownLoadCount(AWorkCount); 
  fOnShowString(’目前下载量:’ + IntToStr(AWorkCount)); 
end; 

procedure TDownLoadThread.OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode; 
  const AWorkCountMax: Integer); 
begin 
  if fFileSize <> 0 then 
    fOnGetFileSize(fFileSize); 
end; 

procedure TDownLoadThread.OnStatus(axSender: TObject; const axStatus: TIdStatus; 
  const asStatusText: String); 
begin 
  fOnShowString(asStatusText); 
end;   

procedure TDownLoadThread.initDownLoad(aWeb: string); 
begin 
  // 论坛的一个文件地址 
  //aWeb = http://www.bc-cn.net/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296 
  // 这里分析得到主机名为 www.bc-cn.net, 要下载的文件是/Soft/ShowSoftDown.asp?UrlID=1&SoftID=296 
  // 这里省略了 
  fIdHttp.Host := ’www.bc-cn.net’; 
  fIdHttp.Port := 80; 
  fIdHttp.HandleRedirects := True;   // 设置重定向 
  fIdHttp.OnRedirect := Self.OnRedirect; 
  fIdHttp.OnStatus := Self.OnStatus; 
end; 

constructor TDownLoadThread.Create(CreateSuspended: Boolean); 
begin 
  fIdHttp :=  TIdHTTP.Create(nil); 
  inherited Create(CreateSuspended); 
end; 

destructor TDownLoadThread.Destroy(); 
begin 
  fIdHttp.Free(); 
  inherited Destroy(); 
end; 

procedure TDownLoadThread.OnRedirect(Sender: TObject; var dest: String; 
  var NumRedirect: Integer; var Handled: Boolean); 
var 
  i: Integer; 
begin 
  i := LastDelimiter(’/’, dest); 
  FDestWebAddr := dest; 
  fDestFileName := Copy(dest, i + 1, Length(dest)); 
  fDownLoadItem := TFileStream.Create(fDestFileName, fmCreate); 
end; 

end. 
  打印新闻关闭窗口