⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tommhttpget.pas

📁 恶意代码查杀软件 很好的一个恶意代码查杀软件
💻 PAS
字号:
unit TommHttpGet;

interface

uses
  Windows, Messages, SysUtils, Classes,WinInet,Forms,dialogs;

//下面是定义httpget的

type TTommHttpGetErrorMessage=(emCanceled,emNetWorkError,emUnknownError);

type
  TOnFileDoneEvent = procedure(Sender: TObject; FileName,url: String; FileSize: Integer;DownloadResult:boolean;aTotalFileCount,aDoneFileCount:integer) of object;
  TOnBeforeFileDownLoad=procedure(Sender:TObject;FileName,url:string) of object;
  TOnAllFileDoneEvent=procedure(Sender:TObject;FileCount:integer) of Object;
  TOnFileProgress=procedure(Sender:TObject;FileName,url:string;FileTotalSize,FileReadedSize:integer) of object;
  TOnFileDownloadError=procedure(Sender:TObject;FileName,url:string;ErrorMessage:TTommHttpGetErrorMessage) of object;

type
  TDownLoadThread=class(TThread)    //下载文件的线程
  private
    FtResult:boolean;
    FDownloadThreadCanceled:boolean;
    FaFileName,FaUrl:string;
    FAgent: string;
    FaUseCache:boolean;
    FaIndex:integer;
    FaFileSize:integer;   //文件大小
    FaReadSize:integer;   //已经完成的字节大小
    FaProgress:TOnFileProgress;  //
    FaErrorFound:TOnFileDownloadError;
    FErrorInfo:TTommHttpGetErrorMessage;  //错误信息
    procedure ThreadDownLoadProgress;
    procedure UpdateProgress;
    procedure DownLoadErrorFound;
  protected
    procedure Execute; override;
  public
    procedure AbortDownLoadThread;
    property tResult:boolean read FtResult;
    property aIndex:integer read FaIndex;
    Constructor Create(Agent, tFileName,tUrl:String;tUseCache:boolean;index:integer;tFileProgrsss:TOnFileProgress);
end;


type
  TTommHTTPGet = class(TComponent)
  private
    FAgent: String;
    FURLList: TStringList;       //远程文件列表
    FFileNameList: TStringList;  //本地文件列表
    FUseCache: Boolean;
    FOnFileDone: TOnFileDoneEvent;
    FOnAllFileDone:TOnAllFileDoneEvent;
    FOnFileProgress:TOnFileProgress;  //单个文件下载的进度
    FOnFileDownloadError:TOnFileDownloadError;  //下载文件错误
    FOnBeforeFileDownLoad:TOnBeforeFileDownLoad;  //开始下载文件    
    FTotalFileCount:integer;
    FDoneFileCount:integer;
    FDownThread:array of TDownLoadThread;

    procedure DownLoadThreadDone(Sender:TObject);
    procedure GetFile(const Url,FileName:string;ThreadIndex:integer);
    procedure CheckThreadStatus;    
  public
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
    procedure CancelDownLoad(ThreadIndex:integer);
    procedure CancelAll;
    procedure BeginDownLoad;
  published
    property Agent: String read FAgent write FAgent;
    property UrlList: TStringList read FUrlList write FUrlList;
    property UseCache: Boolean read FUseCache write FUseCache;
    property FileNameList: TStringList read FFileNameList write FFileNameList;
    property OnFileDone: TOnFileDoneEvent read FOnFileDone write FOnFileDone;
    property OnAllFileDone:TOnAllFileDoneEvent read FOnAllFileDone write FOnAllFileDone;
    property OnFileProgress:TOnFileProgress read FOnFileProgress write FOnFileProgress;
    property OnFileDownloadError:TOnFileDownloadError read FOnFileDownloadError write FOnFileDownloadError;
    property OnBeforeFileDownLoad:TOnBeforeFileDownLoad read FOnBeforeFileDownLoad write FOnBeforeFileDownLoad;
//    property Canceled:boolean read FCanceled;
  end;


implementation


//以下是对httpget的定义及函数

// HTTPGet

procedure TTommHTTPGet.BeginDownLoad;
var i:integer;
begin
  SetLength(FDownThread,FUrlList.Count);
  FDoneFileCount:=0;
  FTotalFileCount:=FUrlList.Count;
  for i:=0 to FUrlList.Count-1 do begin
    GetFile(FUrlList.Strings[i],FFileNameList.Strings[i],i);
  end;
  CheckThreadStatus;
end;

procedure TTommHTTPGet.CancelAll;
var i:integer;
begin
  for i:=0 to High(FDownThread) do begin
     if Assigned(FDownThread[i]) then CancelDownLoad(i); //只能停止还没有结束的线程
  end;
end;

procedure TTommHTTPGet.CancelDownLoad(ThreadIndex:integer);
var WaitTime:integer;
    FDownLoadFileName,FDownLoadUrl:string;
    FDownLoadResult:boolean;
begin
  if ThreadIndex>High(FDownThread) then exit;
  if not Assigned(FDownThread[ThreadIndex]) then exit;  //如果本线程已经结束,则不能取消。


  FDownLoadFileName:=FDownThread[ThreadIndex].FaFileName;
  FDownLoadUrl:=FDownThread[ThreadIndex].FaUrl;
  FDownLoadResult:=false;//  FDownThread[ThreadIndex].FtResult;  //凡是被停止下载的都为下载失败

  if Assigned(FDownThread[ThreadIndex]) then begin
     FDownThread[ThreadIndex].Terminate;
     FDownThread[ThreadIndex].AbortDownLoadThread;
     WaitTime:=0;
     while (WaitTime<5000) and (FDownThread[ThreadIndex]<>nil) do begin
       Application.ProcessMessages;
       inc(WaitTime);
       if not Assigned(FDownThread[ThreadIndex]) then begin
          //if Assigned(FOnFileDone) then FOnFileDone(Self,FDownLoadFileName,FDownLoadUrl,0,FDownLoadResult,FTotalFileCount,FDoneFileCount);
          FDownThread[ThreadIndex]:=nil;
          ///CheckThreadStatus;
          exit;
       end;
       Application.ProcessMessages;
     end;

     //if Assigned(FDownThread) then
     if Assigned(FDownThread[ThreadIndex]) then begin
        TerminateThread(FDownThread[ThreadIndex].Handle,0);
        try
         FDownThread[ThreadIndex].Free;
        except
        end;
        FDownThread[ThreadIndex]:=nil;
        //if Assigned(FOnFileDone) then FOnFileDone(Self, FDownLoadFileName,FDownLoadUrl,0,FDownLoadResult,FTotalFileCount,FDoneFileCount);
        //CheckThreadStatus;
     end;
  end;
end;

procedure TTommHTTPGet.CheckThreadStatus;
var i:integer;
begin
  FDoneFileCount:=0;
  for i:=0 to High(FDownThread) do begin
      if not Assigned(FDownThread[i]) then begin
         Inc(FDoneFileCount);  //已经下载完成数目加1
      end;
  end;

  if FDoneFileCount>=FTotalFileCount then begin   //所有的线程都已经结束了。
     if Assigned(FOnAllFileDone) then FOnAllFileDone(self,FUrlList.Count);
     FUrlList.Clear;
     FFileNameList.Clear;
     SetLength(FDownThread,0);
  end;

//
end;

constructor TTommHttpGet.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);
  FUrlList:=TStringList.Create;
  FFileNameList:=TStringList.Create;
  FAgent := 'Mozilla/4.0(compatible;MSIE5.01;Windows NT5.0)';
end;

destructor TTommHttpGet.Destroy;
begin
  FUrlList.Free;
  FFileNameList.Free;
  inherited Destroy;
end;

procedure TTommHTTPGet.DownLoadThreadDone(Sender: TObject);
var FDownLoadResult:boolean;   //本线程的下载结果
    FDownLoadUrl,FDownLoadFileName:string;   //本线程下载的url和filename
begin
   CheckThreadStatus;
   FDownLoadResult:=TDownLoadThread(Sender).tResult;
   FDownLoadUrl:=TDownLoadThread(Sender).FaUrl;
   FDownLoadFileName:=TDownLoadThread(Sender).FaFileName;
   if Assigned(FOnFileDone) then FOnFileDone(Self, FDownLoadFileName,FDownLoadUrl,0,FDownLoadResult,FTotalFileCount,FDoneFileCount);
//   TDownLoadThread(Sender).Free;
//   FDownThread[TDownLoadThread(Sender).aIndex].Free;
   FDownThread[TDownLoadThread(Sender).aIndex]:=nil; //本线程结束
   CheckThreadStatus;

end;

procedure TTommHttpGet.GetFile(const Url,FileName:string;ThreadIndex:integer);
var tempFileStream:TMemoryStream;
    DownUrl,DownFileName:string;
begin
  if Assigned(FOnBeforeFileDownLoad) then FOnBeforeFileDownLoad(self,FileName,url);
  DownUrl:=url;
  DownFileName:=FileName;

  if (pos('file://',lowercase(DownUrl))>0) or (FileExists(DownUrl))then begin
     delete(DownUrl,1,7);
     DownUrl:=StringReplace(DownUrl,'/','\',[rfReplaceAll, rfIgnoreCase]);
     DownUrl:=StringReplace(DownUrl,'\\','\',[rfReplaceAll, rfIgnoreCase]);
     if FileExists(DownUrl) then begin      //Downurl是一个本地文件,则不需要下载
       tempFileStream:=TMemoryStream.Create;
       try
         tempFileStream.LoadFromFile(DownUrl);
         tempFileStream.SaveToFile(DownFileName);
       except
         if Assigned(FOnFileDone) then FOnFileDone(Self, DownFileName,DownUrl,0,false,FTotalFileCount,FDoneFileCount);
         exit;
       end;
       if Assigned(FOnFileDone) then FOnFileDone(Self, DownFileName,DownUrl,tempFileStream.Size,True,FTotalFileCount,FDoneFileCount);
       tempFileStream.Free;
     end else begin
       if Assigned(FOnFileDone) then FOnFileDone(Self, DownFileName,DownUrl,0,false,FTotalFileCount,FDoneFileCount);
       exit;
    end;
    exit;
  end;

  FDownThread[ThreadIndex]:=TDownLoadThread.Create(FAgent, DownFileName,DownUrl,FUseCache,ThreadIndex,FOnFileProgress);    //远程文件
//  FThreadDone[ThreadIndex]:=false;
//  FCanceled:=false;
  FDownThread[ThreadIndex].FreeOnTerminate:=True;  //线程的释放在DownLoadThreadDown事件中
  FDownThread[ThreadIndex].OnTerminate:=DownLoadThreadDone;
  FDownThread[ThreadIndex].Resume;                               //开始下载
//  while Assigned(FDownThread) do begin
//     Application.ProcessMessages;
//  end;
//  //以上的循环是为了等待线程的完成,如果没有以上循环的话,则成了异步下载
end;

//以上是httpget的函数



{ TDownLoadThread }

procedure TDownLoadThread.AbortDownLoadThread;
begin
  FDownloadThreadCanceled:=True;
end;


constructor TDownLoadThread.Create(Agent, tFileName,tUrl:String;tUseCache:boolean;index:integer;tFileProgrsss:TOnFileProgress);
begin
  FaFileName:=tFileName;
  FaUrl:=tUrl;
  FaUseCache:=tUseCache;
  FDownloadThreadCanceled:=false;
  FaIndex:=index;
  FaProgress:=tFileProgrsss;
  FAgent := Agent;
  inherited Create(True);
end;

procedure TDownLoadThread.DownLoadErrorFound;
begin
  try
    if Assigned(FAErrorFound) then FaErrorFound(Self,FaFileName,FaUrl,FErrorInfo);
  except
  end;
end;

procedure TDownLoadThread.Execute;
begin
  ThreadDownLoadProgress;
  try
    if not FtResult then Synchronize(DownLoadErrorFound);
  except
  end;  
end;

procedure TDownLoadThread.ThreadDownLoadProgress;
const BufferSize = 1024;
var Buffer: array[1..BufferSize] of Byte;
    BufferLen: DWORD;
    f: File;
    hSession,hUrl:hInternet;
    ErrorFound:boolean;
    dwBufLen, dwIndex: DWord;
    Buf: Pointer;
    FTResult: Boolean;    
begin
  ErrorFound:=false;
  FtResult:=false;
  if Terminated then begin
     FErrorInfo:=emCanceled;  //操作被用户终止
     exit;
  end;

  if FAgent <> '' then hSession := InternetOpen(PChar(FAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0)
  else hSession := InternetOpen(nil,INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    if Terminated then begin
       InternetCloseHandle(hSession);
       FErrorInfo:=emCanceled;  //操作被用户终止
       exit;       
    end;  
    hURL := InternetOpenURL(hSession,PChar(FaUrl),nil,0,0,0);
    if (hUrl=nil) or Terminated then begin
       FtResult:=false;
       InternetCloseHandle(hSession);
       FErrorInfo:=emNetWorkError;
       exit;
    end;

    dwIndex  := 0;
    dwBufLen := 1024;
    GetMem(Buf, dwBufLen);
    if HttpQueryInfo(HURL,HTTP_QUERY_CONTENT_LENGTH,Buf,dwBufLen, dwIndex) then begin
       FaFileSize:= StrToInt(StrPas(Buf));
    end;
    FreeMem(Buf);
    //得到要下载文件的大小

    FaReadSize:=0;
    try
      AssignFile(f, FaFileName);
      Rewrite(f,1);
      repeat
        if FDownloadThreadCanceled or Terminated then break;
        InternetReadFile(hURL, @Buffer,SizeOf(Buffer), BufferLen);
        try
          if FDownloadThreadCanceled or Terminated then break;
          BlockWrite(f, Buffer, BufferLen);
          Inc(FaReadSize,BufferLen);
          Synchronize(UpdateProgress);
        except
          ErrorFound:=true;
          break;
        end;
        if FDownloadThreadCanceled or Terminated then break;        
      until BufferLen = 0;
      FaReadSize:=FaFileSize;
      Synchronize(UpdateProgress);      
      CloseFile(f);
      FtResult:=(not ErrorFound) and (not FDownloadThreadCanceled) and (not Terminated);
      if (not FtResult) and (not Terminated) then FErrorInfo:=emUnKnownError  //未知错误
      else FErrorInfo:=emCanceled;
    finally
     FErrorInfo:=emUnKnownError;
     InternetCloseHandle(hURL);
    end
  finally
    InternetCloseHandle(hSession);
 end;

end;

procedure TDownLoadThread.UpdateProgress;
begin
  if Assigned(FaProgress) then
  FaProgress(Self,FaFileName,FaUrl,FaFileSize,FaReadSize);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -