본문 바로가기
DELPHI(델파이)

[델파이 - DELPHI] SFTP Client Class (Devart SecureBridge)

by Jcoder 2020. 11. 24.

unit uSftpClient;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, ComCtrls, StdCtrls, SyncObjs, //

  ScBridge, IdBaseComponent, IdComponent, IdIOHandler, IdIOHandlerSocket, ScIndy, ScSFTPClient, ScSFTPUtils, ScFunctions, TypInfo, ScTypes, ScSSHClient, ScSSHUtils, ScCLRClasses, ScUtils;

 

type

  TSftpClient = class

    sFtpClient : TScSFTPClient;

    sIdHandler : TScIdIOHandler;

    sShClient : TScSSHClient;

    sMemoryStorage : TScMemoryStorage;

    FTimeout : integer;

    FVersion : string;

  private

    sRootDir : string;

    procedure sshClientServerKeyValidate(Sender : TObject; NewServerKey : TScKey; var Accept : Boolean);

    procedure SftpClientConnect(Sender : TObject);

    procedure SftpClientDisconnect(Sender : TObject);

    procedure SftpClientSuccess(Sender : TObject; Operation : TScSFTPOperation; const FileName : stringconst Handle : TArray<Byte>;

      const Message : string);

    procedure SftpClientError(Sender : TObject; Operation : TScSFTPOperation; const FileName : stringconst Handle : TArray<Byte>;

      ErrorCode : integerconst ErrorMessage : stringvar Fail : Boolean);

    procedure SftpClientCreateLocalFile(Sender : TObject; const LocalFileName, RemoteFileName : string; Attrs : TScSFTPFileAttributes; var Handle :

{$IFDEF VER220} Cardinal {$ELSE} NativeUInt {$ENDIF}); overload; // Delphi XE 버전은 Cardinal, 아니면 NativeUInt

    procedure SftpClientDirectoryList(Sender : TObject; const Path : stringconst Handle : TBytes; FileInfo : TScSFTPFileInfo; Eof : Boolean);

 

    procedure scmrystrg1CheckUserKey(Sender : TObject; ClientInfo : TScSSHClientInfo; Key : TScKey; var Accept : Boolean);

    procedure scmrystrg1CheckUserPass(Sender : TObject; ClientInfo : TScSSHClientInfo; const Password : stringvar Accept : Boolean);

  public

    slMsg : TStringList;

    constructor Create(host : string; port : integer; id, pw : string); overload;

    constructor Create(host, port, id, pw : string); overload;

    destructor Destroyoverride;

    procedure Initialize// SFTP 연결

    procedure Finalize// SFTP 연결 해제

    function GetRootDir : string// 루트 경로 읽기

    function IsDirectoryExists(const sSRootDir, sDirectory : string) : Boolean;

    procedure OpenDir(const Path : stringconst SelectedName : string = ''); // 폴더 경로 읽어오기

    procedure RemoveDir(const Path : string); // 디렉토리 삭제

    procedure MakeDir(const DirName : string);

    function GetDirName(const Path : string) : string;

    function GetConnected : Boolean;

    // 다운로드

    function DownloadFile(sFilename, sTargetname : string; bOverWrite : Boolean = True) : Booleanoverload// file -> file

    function DownloadFile(sFilename : string; Target : TMemoryStream) : Booleanoverload// file -> memorystream

    // 업로드

    function UploadFile(sFilename, sTargetname : string; bOverWrite : Boolean = True) : Booleanoverload// file -> file

    function UploadFile(src : TMemoryStream; sTargetname : string; bOverWrite : Boolean = True) : Booleanoverload// memorystream -> file

 

    procedure RenameFile(sOldName, sNewname : string; bOverWrite : Boolean = True);

 

    procedure SetTimeOut(value : integer);

    property Connected : Boolean read GetConnected;

    property Timeout : integer read FTimeout write SetTimeOut default 3600;

    property Version : string read FVersion write FVersion;

  end;

 

  // 한번만 실행할 경우 해당 클래스 이용

  TSftpClientRun = class

    // 다운로드

    // file -> file

    class function DownloadFile(host : string; port : integer; id, pw : string; sFilename, sTargetname : stringvar msg : string;

      bOverWrite : Boolean = True) : Booleanoverload;

    // file -> memorystream

    class function DownloadFile(host : string; port : integer; id, pw : string; sFilename : string; Target : TMemoryStream; var msg : string)

      : Booleanoverload;

    // file -> file

    class function DownloadFile(host, port, id, pw : string; sFilename, sTargetname : stringvar msg : string; bOverWrite : Boolean = True)

      : Booleanoverload;

    // file -> memorystream

    class function DownloadFile(host, port, id, pw : string; sFilename : string; Target : TMemoryStream; var msg : string) : Booleanoverload;

 

    // 업로드 file

    // file -> file

    class function UploadFile(host : string; port : integer; id, pw : string; sFilename, sTargetname : stringvar msg : string;

      bOverWrite : Boolean = True) : Booleanoverload;

    // memorystream -> file

    class function UploadFile(host : string; port : integer; id, pw : string; src : TMemoryStream; sTargetname : stringvar msg : string;

      bOverWrite : Boolean = True) : Booleanoverload;

    // file -> file

    class function UploadFile(host, port, id, pw : string; sFilename, sTargetname : stringvar msg : string; bOverWrite : Boolean = True)

      : Booleanoverload;

    // memorystream -> file

    class function UploadFile(host, port, id, pw : string; src : TMemoryStream; sTargetname : stringvar msg : string; bOverWrite : Boolean = True)

      : Booleanoverload;

  end;

 

const

  BUFFER_SIZE = 262146;

 

implementation

 

{ TSftpClient }

 

constructor TSftpClient.Create(host : string; port : integer; id, pw : string);

begin

  sFtpClient     := TScSFTPClient.Create(nil);

  sIdHandler     := TScIdIOHandler.Create(nil);

  sShClient      := TScSSHClient.Create(nil);

  sMemoryStorage := TScMemoryStorage.Create(nil);

  slMsg          := TStringList.Create;

  try

    if FTimeout = 0 then

      FTimeout := 3600;

 

    if FVersion = '' then

      FVersion := 'vSFTP6';

 

    sRootDir := '/'// 최상위 경로

    // SFTP Client

    sFtpClient.sShClient      := sShClient;

    sFtpClient.ReadBlockSize  := BUFFER_SIZE;

    sFtpClient.WriteBlockSize := BUFFER_SIZE;

    sFtpClient.UseUnicode     := True;

    sFtpClient.Timeout        := Timeout;

    // sFtpClient.NonBlocking := True;

    // sFtpClient.EventsCallMode := ecSynchronous;

 

    sFtpClient.Version           := TScSFTPVersion(GetEnumValue(TypeInfo(TScSFTPVersion), Version));

    sFtpClient.OnConnect         := SftpClientConnect;

    sFtpClient.OnDisconnect      := SftpClientDisconnect;

    sFtpClient.OnSuccess         := SftpClientSuccess;

    sFtpClient.OnError           := SftpClientError;

    sFtpClient.OnDirectoryList   := SftpClientDirectoryList;

    sFtpClient.OnCreateLocalFile := SftpClientCreateLocalFile;

 

    // Id Handler

    sIdHandler.RecvBufferSize := BUFFER_SIZE;

    sIdHandler.SendBufferSize := BUFFER_SIZE;

    sIdHandler.Client         := sShClient;

    sIdHandler.ReadTimeout    := Timeout;

 

    // TScMemoryStorage

    sMemoryStorage.StoreUserPassword := True;

    sMemoryStorage.OnCheckUserKey    := scmrystrg1CheckUserKey;

    sMemoryStorage.OnCheckUserPass   := scmrystrg1CheckUserPass;

 

    // SSH Client

    sShClient.KeyStorage                      := sMemoryStorage;

    sShClient.Authentication                  := atPassword;

    sShClient.Hostname                        := host;

    sShClient.port                            := port;

    sShClient.User                            := id;

    sShClient.Password                        := pw;

    sShClient.Timeout                         := Timeout;

    sShClient.Options.SocketReceiveBufferSize := BUFFER_SIZE;

    sShClient.Options.SocketSendBufferSize    := BUFFER_SIZE;

    sShClient.Options.ServerAliveCountMax     := 5000;

    sShClient.HostKeyAlgorithms.AsString      := 'ssh-rsa,ssh-dss';

    sShClient.OnServerKeyValidate             := sshClientServerKeyValidate;

 

    Initialize;

  except

    on E : Exception do

      slMsg.Add(E.Message);

  end;

end;

 

constructor TSftpClient.Create(host, port, id, pw : string);

begin

  Create(host, StrToInt(port), id, pw);

end;

 

destructor TSftpClient.Destroy;

begin

  Finalize;

 

  if Assigned(slMsg) then

  begin

    slMsg.Clear;

{$IFDEF VER220} slMsg.Free; {$ELSE} slMsg.DisposeOf; {$ENDIF}

  end;

 

  if Assigned(sMemoryStorage) then

{$IFDEF VER220} sMemoryStorage.Free; {$ELSE} sMemoryStorage.DisposeOf; {$ENDIF}

  if Assigned(sShClient) then

{$IFDEF VER220} sShClient.Free; {$ELSE} sShClient.DisposeOf; {$ENDIF}

  if Assigned(sIdHandler) then

{$IFDEF VER220} sIdHandler.Free; {$ELSE} sIdHandler.DisposeOf; {$ENDIF}

  if Assigned(sFtpClient) then

{$IFDEF VER220} sFtpClient.Free; {$ELSE} sFtpClient.DisposeOf; {$ENDIF}

  inherited;

end;

 

procedure TSftpClient.Initialize// SFTP 연결

begin

  try

    sShClient.connect;

    if sShClient.Connected then

      sFtpClient.Initialize

    else

      slMsg.Add('not connected sShClient');

    // OpenDir(sRootDir);

  except

    on E : Exception do

      slMsg.Add(E.Message);

  end;

end;

 

procedure TSftpClient.Finalize// SFTP 연결 해제

begin

  try

    if sShClient.Connected then

      sShClient.Disconnect;

    if sFtpClient.Active then

      sFtpClient.Disconnect;

  except

    on E : Exception do

      slMsg.Add(E.Message);

  end;

 

end;

 

function TSftpClient.GetConnected : Boolean;

begin

  Result := False;

  if sShClient.Connected and sFtpClient.Active then

    Result := True;

end;

 

function TSftpClient.GetDirName(const Path : string) : string;

var

  sTmpPath : string;

  i : integer;

begin

  Result := '';

  // 폴더 경로 추출

  sTmpPath := StringReplace(Path, '/''\', [rfReplaceAll]);

  sTmpPath := ExtractFileDir(sTmpPath);

 

  for i := Length(sTmpPath) downto 1 do

  begin

    if sTmpPath[i] = '\' then

    begin

      sRootDir := Copy(sTmpPath, 0, i);

      sTmpPath := Copy(sTmpPath, Length(sTmpPath) - i, i + 1);

      Break;

    end;

  end;

 

  // SFTP에 디렉토리가 없으면 디렉토리 생성을 위해 경로 \ -> ''로 바꾸기 1

  Result := StringReplace(sTmpPath, '\''/', [rfReplaceAll]);

end;

 

function TSftpClient.GetRootDir : string;

begin

  Result := sRootDir;

  if IsDelimiter('/', Result, Length(Result)) and (Result[Length(Result)] = '/'then

    Exit;

  if IsDelimiter('\', Result, Length(Result)) and (Result[Length(Result)] = '\'then

    Exit;

 

  Result := Result + '/';

end;

 

function TSftpClient.IsDirectoryExists(const sSRootDir, sDirectory : string) : Boolean;

var

  i : integer;

  List : TCRObjectList;

  Handle : TScSFTPFileHandle;

begin

  Result := False;

 

  Handle := sFtpClient.OpenDirectory(sSRootDir);

 

  List := TCRObjectList.Create;

  try

    sFtpClient.ReadDirectoryToList(Handle, List);

 

    for i := 0 to List.Count - 1 do

    begin

      if (TScSFTPFileInfo(List.Items[i]).Longname[1] = 'd'and (TScSFTPFileInfo(List.Items[i]).FileName = sDirectory) then

      begin

        Result := True;

        Break;

      end;

    end;

  finally

    sFtpClient.CloseHandle(Handle);

    FreeAndNil(List);

  end;

end;

 

procedure TSftpClient.OpenDir(const Path : stringconst SelectedName : string = '');

var

  Handle : TScSFTPFileHandle;

  RootDir : string;

begin

  RootDir  := sFtpClient.RetrieveAbsolutePath(Trim(Path));

  Handle   := sFtpClient.OpenDirectory(RootDir);

  sRootDir := RootDir;

 

  try

    try

      while not sFtpClient.Eof(Handle) do

        sFtpClient.ReadDirectory(Handle);

    except

      on E : Exception do

      begin

        OutputDebugString(PWideChar(E.Message));

        slMsg.Add(Format('OpenDir Error : %s', [E.Message]));

      end;

 

    end;

  finally

    sFtpClient.CloseHandle(Handle);

  end;

end;

 

procedure TSftpClient.RemoveDir(const Path : string);

begin

  //

end;

 

procedure TSftpClient.RenameFile(sOldName, sNewname : string; bOverWrite : Boolean = True);

begin

  slMsg.Clear;

 

  sOldName := StringReplace(sOldName, '\''/', [rfReplaceAll]);

  sNewname := StringReplace(sNewname, '\''/', [rfReplaceAll]);

  try

    if bOverWrite then

    begin

      sFtpClient.RenameFile(sOldName, sNewname, [TScSFTPRenameFlag.rfOverwrite]);

    end

    else

    begin

      {

       Filename : Unpaid_20201118_01.dat, Error Cdoe : 8, Error Message : Operation unsupported

       https://www.devart.com/sbridge/docs/index.html?tscsftprenameflag.htm

       rfNative if this flag is included and there is not possible to replace the destination in an atomic fashion, then the SSH_FX_OP_UNSUPPORTED error will be returned

      }

      sFtpClient.RenameFile(sOldName, sNewname, []);

    end;

  except

    on E : Exception do

      slMsg.Add(Format('RenameFile Error : %s', [E.Message]));

  end;

end;

 

procedure TSftpClient.scmrystrg1CheckUserKey(Sender : TObject; ClientInfo : TScSSHClientInfo; Key : TScKey; var Accept : Boolean);

begin

  Accept := True;

end;

 

procedure TSftpClient.scmrystrg1CheckUserPass(Sender : TObject; ClientInfo : TScSSHClientInfo; const Password : stringvar Accept : Boolean);

begin

  Accept := True;

  slMsg.Add(Format('Password : %s', [Password]));

end;

 

procedure TSftpClient.MakeDir(const DirName : string);

begin

  if DirName <> '' then

    sFtpClient.MakeDirectory(GetRootDir + DirName);

  OpenDir(GetRootDir + DirName);

end;

 

function TSftpClient.DownloadFile(sFilename : string; Target : TMemoryStream) : Boolean;

var

  tmpStream : TMemoryStream;

begin

  Result := False;

  slMsg.Clear;

 

  sFilename := StringReplace(sFilename, '\''/', [rfReplaceAll]);

 

  tmpStream := TMemoryStream.Create;

  try

    try

      sFtpClient.DownloadToStream(GetRootDir + sFilename, tmpStream, 0);

 

      Target.Clear;

      Target.LoadFromStream(tmpStream);

 

      Result := True;

    except

      on E : Exception do

      begin

        slMsg.Add(Format('Download Error : %s', [E.Message]));

        Result := False;

      end;

    end;

  finally

    tmpStream.Free;

  end;

end;

 

function TSftpClient.DownloadFile(sFilename, sTargetname : string; bOverWrite : Boolean = True) : Boolean;

var

  bNext : Boolean;

begin

  Result := False;

  bNext  := True;

  slMsg.Clear;

 

  sFilename   := StringReplace(sFilename, '\''/', [rfReplaceAll]);

  sTargetname := StringReplace(sTargetname, '/''\', [rfReplaceAll]);

 

  if not SysUtils.DirectoryExists(ExtractFilePath(sTargetname)) then

    bNext := SysUtils.ForceDirectories(ExtractFilePath(sTargetname)); // 폴더 생성.

 

  if bNext then

  begin

    try

      sFtpClient.DownloadFile(GetRootDir + sFilename, sTargetname, bOverWrite, 0);

    except

      on E : Exception do

      begin

        slMsg.Add(Format('Download Error : %s', [E.Message]));

        Result := False;

      end;

    end;

  end;

 

  if FileExists(sTargetname) then

    Result := True;

end;

 

function TSftpClient.UploadFile(src : TMemoryStream; sTargetname : string; bOverWrite : Boolean = True) : Boolean;

var

  tmpStream : TMemoryStream;

begin

  Result := False;

  slMsg.Clear;

 

  // 파일 경로 바꾸기

  sTargetname := StringReplace(sTargetname, '\''/', [rfReplaceAll]);

 

  tmpStream := TMemoryStream.Create;

  try

    try

      src.SaveToStream(tmpStream);

      // src.Seek(0, soFromBeginning);

      // tmpStream.CopyFrom(src, src.Size);

      // tmpStream.Seek(0, soFromBeginning);

      src.Clear;

 

      sFtpClient.UploadFromStream(tmpStream, GetRootDir + sTargetname, bOverWrite, 0);

 

      Result := True;

    except

      on E : Exception do

      begin

        slMsg.Add(Format('Upload Error : %s', [E.Message]));

        Result := False;

      end;

    end;

  finally

    tmpStream.Free;

  end;

end;

 

function TSftpClient.UploadFile(sFilename, sTargetname : string; bOverWrite : Boolean = True) : Boolean;

begin

  Result := False;

  slMsg.Clear;

 

  // 업로드 할 로컬 파일이 존재 해야 진행

  if FileExists(sFilename) then

  begin

    sTargetname := StringReplace(sTargetname, '\''/', [rfReplaceAll]);

 

    try

      sFtpClient.UploadFile(sFilename, GetRootDir + sTargetname, bOverWrite, 0);

      Result := True;

    except

      on E : Exception do

      begin

        slMsg.Add(Format('Upload Error : %s', [E.Message]));

        Result := False;

      end;

    end;

  end;

end;

 

procedure TSftpClient.SetTimeOut(value : integer);

begin

  sFtpClient.Timeout     := value;

  sIdHandler.ReadTimeout := value;

  sShClient.Timeout      := value;

end;

 

procedure TSftpClient.SftpClientConnect(Sender : TObject);

begin

  OutputDebugString(PWideChar('Sftp Clinet Connect'));

  slMsg.Add(Format('%s - Sftp Clinet Connect', [FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz', Now)]));

end;

 

procedure TSftpClient.SftpClientCreateLocalFile(Sender : TObject; const LocalFileName, RemoteFileName : string; Attrs : TScSFTPFileAttributes;

  var Handle : {$IFDEF VER220} Cardinal {$ELSE} NativeUInt {$ENDIF});

var

  dwFlags : DWORD;

begin

  if aAttrs in Attrs.ValidAttributes then

  begin

    dwFlags := 0;

    if faReadOnly in Attrs.Attrs then

      dwFlags := dwFlags or FILE_ATTRIBUTE_READONLY;

    if faSystem in Attrs.Attrs then

      dwFlags := dwFlags or FILE_ATTRIBUTE_SYSTEM;

    if faHidden in Attrs.Attrs then

      dwFlags := dwFlags or FILE_ATTRIBUTE_HIDDEN;

    if faArchive in Attrs.Attrs then

      dwFlags := dwFlags or FILE_ATTRIBUTE_ARCHIVE;

    if faCompressed in Attrs.Attrs then

      dwFlags := dwFlags or FILE_ATTRIBUTE_COMPRESSED;

  end

  else

    dwFlags := FILE_ATTRIBUTE_NORMAL;

 

  Handle := CreateFile(PChar(LocalFileName), GENERIC_READ or GENERIC_WRITE, 0nil, CREATE_NEW, dwFlags, 0);

end;

 

procedure TSftpClient.SftpClientDirectoryList(Sender : TObject; const Path : stringconst Handle : TBytes; FileInfo : TScSFTPFileInfo;

  Eof : Boolean);

begin

  if (FileInfo = nilor (FileInfo.FileName = '.'then

    Exit;

end;

 

procedure TSftpClient.SftpClientDisconnect(Sender : TObject);

begin

  //

  OutputDebugString(PWideChar('Sftp Clinet DisConnect'));

  slMsg.Add(Format('%s - Sftp Clinet DisConnect', [FormatDateTime('yyyy/mm/dd hh:nn:ss.zzz', Now)]));

end;

 

procedure TSftpClient.SftpClientError(Sender : TObject; Operation : TScSFTPOperation; const FileName : stringconst Handle : TArray<Byte>;

  ErrorCode : integerconst ErrorMessage : stringvar Fail : Boolean);

begin

  //

  slMsg.Add(Format('Filename : %s, Error Cdoe : %d, Error Message : %s', [FileName, ErrorCode, ErrorMessage]));

end;

 

procedure TSftpClient.SftpClientSuccess(Sender : TObject; Operation : TScSFTPOperation; const FileName : stringconst Handle : TArray<Byte>;

  const Message : string);

begin

  //

  slMsg.Add(Format('Filename : %s, Success Message : %s', [FileName, Message]));

end;

 

procedure TSftpClient.sshClientServerKeyValidate(Sender : TObject; NewServerKey : TScKey; var Accept : Boolean);

var

  CurHostKeyName : string;

  Key : TScKey;

  fp : string;

begin

  if sShClient.HostKeyName = '' then

    CurHostKeyName := sShClient.Hostname

  else

    CurHostKeyName := sShClient.HostKeyName;

 

  Key := sMemoryStorage.Keys.FindKey(CurHostKeyName);

  if (Key = nilor not Key.Ready then

  begin

    NewServerKey.GetFingerPrint(haMD5, fp);

    // slMsg.add(Format('fp : %s, CurHostKeyName : %s', [fp, CurHostKeyName]));

    Key := TScKey.Create(nil);

    try

      Key.Assign(NewServerKey);

      Key.KeyName := CurHostKeyName;

      sMemoryStorage.Keys.Add(Key);

    except

      on E : Exception do

      begin

        slMsg.Add(E.Message);

        Key.Free;

      end;

    end;

    Accept := True; // 로그인시 필요.

  end;

end;

 

{ TSftpClientRun }

 

class function TSftpClientRun.DownloadFile(host : string; port : integer; id, pw, sFilename, sTargetname : stringvar msg : string;

  bOverWrite : Boolean = True) : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.DownloadFile(sFilename, sTargetname, bOverWrite);

    except

      on E : Exception do

        v.slMsg.Add(E.Message);

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.DownloadFile(host : string; port : integer; id, pw, sFilename : string; Target : TMemoryStream; var msg : string)

  : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.DownloadFile(sFilename, Target);

    except

      on E : Exception do

        v.slMsg.Add(E.Message);

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.DownloadFile(host, port, id, pw, sFilename, sTargetname : stringvar msg : string; bOverWrite : Boolean = True)

  : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.DownloadFile(sFilename, sTargetname, bOverWrite);

    except

      on E : Exception do

        v.slMsg.Add(E.Message);

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.DownloadFile(host, port, id, pw, sFilename : string; Target : TMemoryStream; var msg : string) : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.DownloadFile(sFilename, Target);

    except

      on E : Exception do

        v.slMsg.Add(E.Message);

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.UploadFile(host : string; port : integer; id, pw, sFilename, sTargetname : stringvar msg : string;

  bOverWrite : Boolean = True) : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.UploadFile(sFilename, sTargetname, bOverWrite);

    except

      on E : Exception do

      begin

        v.slMsg.Add(E.Message);

      end;

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.UploadFile(host : string; port : integer; id, pw : string; src : TMemoryStream; sTargetname : stringvar msg : string;

  bOverWrite : Boolean = True) : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.UploadFile(src, sTargetname, bOverWrite);

    except

      on E : Exception do

      begin

        v.slMsg.Add(E.Message);

      end;

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.UploadFile(host, port, id, pw, sFilename, sTargetname : stringvar msg : string; bOverWrite : Boolean = True)

  : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.UploadFile(sFilename, sTargetname, bOverWrite);

    except

      on E : Exception do

      begin

        v.slMsg.Add(E.Message);

      end;

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

class function TSftpClientRun.UploadFile(host, port, id, pw : string; src : TMemoryStream; sTargetname : stringvar msg : string;

  bOverWrite : Boolean = True) : Boolean;

var

  v : TSftpClient;

begin

  Result := False;

  v      := TSftpClient.Create(host, port, id, pw);

  try

    try

      Result := v.UploadFile(src, sTargetname, bOverWrite);

    except

      on E : Exception do

      begin

        v.slMsg.Add(E.Message);

      end;

    end;

  finally

    msg := v.slMsg.text;

    v.Free;

  end;

end;

 

end.

 

 Delphi SSH, SFTP, FTPS, SSL, HTTP/HTTPS, WebSocket and SignalR Сlient and Server (devart.com)

 

SecureBridge - Library of Nonvisual Components

Cross-Platform Solution for Delphi and C++Builder The high-performance and feature-rich component library offers cross-platform solutions for developing applications using various IDEs and editions including Community Edition: RAD Studio, Delphi, C++Builde

www.devart.com

컴포넌트 사용하기.