Tidftp实现自动更新程序

unit uFrmSplash;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, jpeg, ExtCtrls, StdCtrls, IdBaseComponent,
  IdComponent, IdTCPConnection, IdTCPClient, IdFTP,IniFiles,IdFTPList;

const
  wm_closeProcess=WM_USER + $1000;

type
  TfrmSplash = class(TForm)
    Image1: TImage;
    IdFTP1: TIdFTP;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure connectFtpServer;
    procedure closeProcess(var Msg: TMessage); message wm_closeProcess;
  public
    { Public declarations }
  end;

  Tdown=class(TThread)
  private
    procedure downLoad;
    procedure CloseMainProcess(fileName:string); //关闭主程序进程
    procedure OpenMainProcess(fileName:string);  //开启主程序进程
    procedure display(aCaption:string);          //显示更新的进度
  protected
    procedure execute; override;
  public
    constructor create;
  end;

var
  frmSplash: TfrmSplash;
  sl:TStringList;
 
  {ftp参数}
  fuser:string;
  fpassword:string;
  fserver:string;
  fport:string;
  fdir:string;
  fexeFile:string;

implementation

uses uFTPclient;

{$R *.dfm}

{ TfrmSplash }

procedure Tdown.CloseMainProcess(fileName: string);
begin
  if (ExtractFileExt(fileName)='.exe') or
    (ExtractFileExt(fileName)='.com') then
  begin
    if IsFileInUse(fileName) then
    begin
      KillProcess(fileName);
    end; 
  end; 
end;

procedure Tdown.download;
var
  filename,filename2,filename3,filename4,filename5:string;
  temp,temp2,temp3,temp4,temp5,temp6,temp7,temp8:string;
  i,j,k,l,m:Integer;
begin
  if not frmSplash.IdFTP1.Connected then Exit;
 
  sl:=TStringList.Create;
  try
  with frmSplash.IdFTP1 do
  begin
    try
      ChangeDir(fdir);
      List(sl);

      if DirectoryListing.Count=0 then Exit;

      for i:=0 to DirectoryListing.Count-1 do
      begin
        if not (DirectoryListing.Items[i].ItemType=ditDirectory) then
        begin
          filename:=DirectoryListing.Items[i].FileName;
         
          if FileExists(ExtractFilePath(ParamStr(0))+filename) then
          begin
            {已经存在的文件,要检查它的最后的修改时间,判断它是否是最新}
            if GetFileLastAccessTime(ExtractFilePath(ParamStr(0))+filename,
              FILE_MODIFY_TIME)<DirectoryListing.Items[i].ModifiedDate then
            begin
              CloseMainProcess(filename);
              {备份原文件}
              if FileExists(ExtractFilePath(ParamStr(0))+filename+'.bak') then
                DeleteFile(ExtractFilePath(ParamStr(0))+filename+'.bak');
              CopyFile(PChar(ExtractFilePath(ParamStr(0))+filename),
                PChar(ExtractFilePath(ParamStr(0))+filename+'.bak'),False);
              {下载新文件}
              if FileExists(ExtractFilePath(ParamStr(0))+filename) then
                DeleteFile(ExtractFilePath(ParamStr(0))+filename);
              try
                display(ExtractFilePath(ParamStr(0))+filename);
                Get(filename,ExtractFilePath(ParamStr(0))+filename,false);
                SetFileLastWriteTime(ExtractFilePath(ParamStr(0))+filename,
                  DirectoryListing.Items[i].ModifiedDate);
              except
                on E:Exception do
                  raise Exception.Create(e.Message);
              end;
            end; 
          end
          else
          begin
            {下载新增的文件}
            try
              display(ExtractFilePath(ParamStr(0))+filename);
              Get(filename,ExtractFilePath(ParamStr(0))+filename,false);
              SetFileLastWriteTime(ExtractFilePath(ParamStr(0))+filename,
                  DirectoryListing.Items[i].ModifiedDate);
            except
              on E:Exception do
                raise Exception.Create(e.Message);
            end;
          end;
        end
        else
        begin
          {二级子目录}
          temp:=fdir+'/'+DirectoryListing.Items[i].FileName;
          temp3:=ExtractFilePath(ParamStr(0))+DirectoryListing.Items[i].FileName;
          if not DirectoryExists(temp3) then
            MkDir(temp3);
          
          ChangeDir(temp);
          List(sl);

          if DirectoryListing.Count=0 then Exit;

          for j:=0 to DirectoryListing.Count-1 do
          begin
            if not (DirectoryListing.Items[j].ItemType=ditDirectory) then
            begin
              filename2:=DirectoryListing.Items[j].FileName;

              if FileExists(temp3+'/'+filename2) then
              begin
                {已经存在的文件,要检查它的最后的修改时间,判断它是否是最新}
                if GetFileLastAccessTime(temp3+'/'+filename2,FILE_MODIFY_TIME)<
                  DirectoryListing.Items[j].ModifiedDate then
                begin
                  CloseMainProcess(filename2);
                  {备份原文件}
                  if FileExists(temp3+'/'+filename2+'.bak') then
                    DeleteFile(temp3+'/'+filename2+'.bak');
                  CopyFile(PChar(temp3+'/'+filename2),
                    PChar(temp3+'/'+filename2+'.bak'),False);
                  {下载新文件}
                  if FileExists(temp3+'/'+filename2) then
                    DeleteFile(temp3+'/'+filename2);
                  try
                    display(temp3+'/'+filename2);
                    Get(filename2,temp3+'/'+filename2,false);
                    SetFileLastWriteTime(temp3+'/'+filename2,
                      DirectoryListing.Items[j].ModifiedDate);
                  except
                    on E:Exception do
                      raise Exception.Create(e.Message);
                  end;
                end; 
              end
              else
              begin
                {下载新增的文件}
                if not DirectoryExists(temp3) then
                  MkDir(temp3);
                try
                  display(temp3+'/'+filename2);
                  Get(filename2,temp3+'/'+filename2,false);
                  SetFileLastWriteTime(temp3+'/'+filename2,
                    DirectoryListing.Items[j].ModifiedDate);
                except
                  on E:Exception do
                    raise Exception.Create(e.Message);
                end;
              end;
            end
            else
            begin
              {三级子目录}
              temp2:=temp+'/'+DirectoryListing.Items[j].FileName;
              temp4:=temp3+'/'+DirectoryListing.Items[j].FileName;
              if not DirectoryExists(temp4) then
                MkDir(temp4);

              ChangeDir(temp2);
              List(sl);

              if DirectoryListing.Count=0 then exit;

              for k:=0 to DirectoryListing.Count-1 do
              begin
                if not (DirectoryListing.Items[k].ItemType=ditDirectory) then
                begin
                  filename3:=DirectoryListing.Items[k].FileName;

                  if FileExists(temp4+'/'+filename3) then
                  begin
                    if GetFileLastAccessTime(temp4+'/'+filename3,
                      FILE_MODIFY_TIME)<DirectoryListing.Items[k].ModifiedDate then
                    begin
                      CloseMainProcess(filename3);
                      {备份原文件}
                      if FileExists(temp4+'/'+filename3+'.bak') then
                        DeleteFile(temp4+'/'+filename3+'.bak');
                      CopyFile(PChar(temp4+'/'+filename3),
                        PChar(temp4+'/'+filename3+'.bak'),False);
                      {下载新文件}
                      if FileExists(temp4+'/'+filename3) then
                        DeleteFile(temp4+'/'+filename3);
                      try
                        display(temp4+'/'+filename3);
                        Get(filename3,temp4+'/'+filename3,false);
                        SetFileLastWriteTime(temp4+'/'+filename3,
                          DirectoryListing.Items[k].ModifiedDate);
                      except
                        on E:Exception do
                          raise Exception.Create(e.Message);
                      end;
                    end; 
                  end
                  else
                  begin
                    {下载新增的文件}
                    if not DirectoryExists(temp4) then
                      MkDir(temp4);
                    try
                      display(temp4+'/'+filename3);
                      Get(filename3,temp4+'/'+filename3,false);
                      SetFileLastWriteTime(temp4+'/'+filename3,
                        DirectoryListing.Items[k].ModifiedDate);
                    except
                      on E:Exception do
                        raise Exception.Create(e.Message);
                    end;
                  end;   
                end
                else
                begin
                  {四级子目录}
                  temp5:=temp2+'/'+DirectoryListing.Items[k].FileName;
                  temp6:=temp4+'/'+DirectoryListing.Items[k].FileName;
                  if not DirectoryExists(temp6) then
                    MkDir(temp6);

                  ChangeDir(temp5);
                  List(sl);

                  if DirectoryListing.Count=0 then exit;

                  for l:=0 to DirectoryListing.Count-1 do
                  begin
                    if not (DirectoryListing.Items[l].ItemType=ditDirectory) then
                    begin
                      filename4:=DirectoryListing.Items[l].FileName;

                      if FileExists(temp6+'/'+filename4) then
                      begin
                        if GetFileLastAccessTime(temp6+'/'+filename4,
                          FILE_MODIFY_TIME)<DirectoryListing.Items[l].ModifiedDate then
                        begin
                          CloseMainProcess(filename4);
                          {备份原文件}
                          if FileExists(temp6+'/'+filename4+'.bak') then
                            DeleteFile(temp6+'/'+filename4+'.bak');
                          CopyFile(PChar(temp6+'/'+filename4),
                            PChar(temp6+'/'+filename4+'.bak'),False);
                          {下载新文件}
                          if FileExists(temp6+'/'+filename4) then
                            DeleteFile(temp6+'/'+filename4);
                          try
                            display(temp6+'/'+filename4);
                            Get(filename4,temp6+'/'+filename4,false);
                            SetFileLastWriteTime(temp6+'/'+filename4,
                              DirectoryListing.Items[l].ModifiedDate);
                          except
                            on E:Exception do
                              raise Exception.Create(e.Message);
                          end;
                        end;
                      end
                      else
                      begin
                        {下载新增的文件}
                        if not DirectoryExists(temp6) then
                          MkDir(temp6);
                        try
                          display(temp6+'/'+filename4);
                          Get(filename4,temp6+'/'+filename4,false);
                          SetFileLastWriteTime(temp6+'/'+filename4,
                            DirectoryListing.Items[l].ModifiedDate);
                        except
                          on E:Exception do
                            raise Exception.Create(e.Message);
                        end;
                      end;
                    end
                    else
                    begin
                      {五级子目录}
                      temp7:=temp5+'/'+DirectoryListing.Items[l].FileName;
                      temp8:=temp6+'/'+DirectoryListing.Items[l].FileName;
                      if not DirectoryExists(temp8) then
                        MkDir(temp8);

                      ChangeDir(temp7);
                      List(sl);

                      if DirectoryListing.Count=0 then exit;

                      for m:=0 to DirectoryListing.Count-1 do
                      begin
                        if not (DirectoryListing.Items[m].ItemType=ditDirectory) then
                        begin
                          filename5:=DirectoryListing.Items[m].FileName;

                          if FileExists(temp8+'/'+filename5) then
                          begin
                            if GetFileLastAccessTime(temp8+'/'+filename5,
                              FILE_MODIFY_TIME)<DirectoryListing.Items[m].ModifiedDate then
                            begin
                              CloseMainProcess(filename5);
                              {备份原文件}
                              if FileExists(temp8+'/'+filename5+'.bak') then
                                DeleteFile(temp8+'/'+filename5+'.bak');
                              CopyFile(PChar(temp8+'/'+filename5),
                                PChar(temp8+'/'+filename5+'.bak'),False);
                              {下载新文件}
                              if FileExists(temp8+'/'+filename5) then
                                DeleteFile(temp8+'/'+filename5);
                              try
                                display(temp8+'/'+filename5);
                                Get(filename5,temp8+'/'+filename5,false);
                                SetFileLastWriteTime(temp8+'/'+filename5,
                                  DirectoryListing.Items[m].ModifiedDate);
                              except
                                on E:Exception do
                                  raise Exception.Create(e.Message);
                              end;
                            end;
                          end
                          else
                          begin
                            {下载新增的文件}
                            if not DirectoryExists(temp8) then
                              MkDir(temp8);
                            try
                              display(temp8+'/'+filename5);
                              Get(filename5,temp8+'/'+filename5,false);
                              SetFileLastWriteTime(temp8+'/'+filename5,
                                DirectoryListing.Items[m].ModifiedDate);
                            except
                              on E:Exception do
                                raise Exception.Create(e.Message);
                            end;
                          end; 
                        end; 
                      end;

                      ChangeDir(temp5);
                      List(sl);
                    end;   
                  end;

                  ChangeDir(temp2);
                  List(sl);
                end;
              end;

              ChangeDir(temp);
              List(sl);
            end; 
          end; 

          ChangeDir(fdir);
          List(sl);
        end;
      end;

      frmSplash.IdFTP1.Quit;
    except
      on E:Exception do
        raise Exception.Create(E.Message);
    end;
  end;
  finally
    FreeAndNil(sl);
  end;
end;

procedure TfrmSplash.closeProcess(var Msg: TMessage);
begin
  Application.Terminate;
end;

procedure TfrmSplash.connectFtpServer;
var
  ini:TIniFile;
  section:string;
begin
  if not FileExists(ExtractFilePath(ParamStr(0))+'update.ini') then
  begin
    raise Exception.Create('找不到update.ini文件,更新失败');
    Application.Terminate;
  end; 

  {取ftp参数}
  ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'update.ini');
  try
    section:='server';
    fuser:=ini.ReadString(section,'username','');
    fpassword:=ini.ReadString(section,'password','');
    fserver:=ini.ReadString(section,'host','');
    fport:=ini.ReadString(section,'port','');
    fdir:=ini.ReadString(section,'directory','');
    fexeFile:=ini.ReadString(section,'exe','');
  finally
    ini.Free;
  end;

  with IdFTP1 do
  begin
    Host:=fserver;
    Port:=StrToInt(fport);
    Username:=fuser;
    Password:=fpassword;
    try
      Connect();
    except
      on E:Exception do
      begin
        Application.Terminate;
      end;
    end; 
  end; 
end;

procedure TfrmSplash.FormCreate(Sender: TObject);
var
  t:Tdown;
begin
  connectFtpServer;

  t:=Tdown.create;
end;

procedure Tdown.OpenMainProcess(fileName: string);
begin
  if FileExists(fexeFile) then
  if FindProcessId(fexeFile)=0 then
    WinExec(PChar(fexeFile),SW_SHOW);
end;

procedure Tdown.display(aCaption: string);
begin
  TextOut(GetDC(frmSplash.Handle),1,343,PChar('更新文件'+aCaption),
    Length('更新文件'+aCaption));
end;

procedure Tdown.execute;
begin
  inherited;
  downLoad;
  OpenMainProcess(fexeFile);
  PostMessage(frmSplash.Handle,wm_closeProcess,0,0);
end;

constructor Tdown.create;
begin
  inherited create(False);
  FreeOnTerminate:=True;
end;

end.

原文地址:https://www.cnblogs.com/hnxxcxg/p/2940977.html