Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Delphi 10.4 - Indy und SFTP (https://www.delphipraxis.net/208298-delphi-10-4-indy-und-sftp.html)

jaenicke 20. Apr 2023 20:36

AW: Delphi 10.4 - Indy und SFTP
 
Der Ablauf:
Delphi-Quellcode:
procedure ListDir;
begin
  ...
  if Assigned(FOnSFTPListing) then
    FOnSFTPListing(Self, Items);
end;
Sprich du gibst der Komponente in der Eigenschaft OnSFTPListing eine Referenz auf deine Prozedur TGPuttySFTPClient1SFTPListing. Die Komponente ruft dann deine Prozedur auf, wenn sie das Listing erhalten hat. Hintergrund ist vermutlich, dass das asynchron funktioniert, sprich ListDir schon wieder beendet ist, wenn das Ergebnis ankommt und deine Ereignisprozedur aufgerufen wird.

jaenicke 20. Apr 2023 21:47

AW: Delphi 10.4 - Indy und SFTP
 
Da ich sehe, dass du online bist, mache ich mal eine neue Antwort:
Stell dir das einfach so vor...

Du gehst zur Hotelrezeption (die SFTP-Komponente) und lässt dir ein Taxi rufen. Dort hinterlegst du deine Telefonnummer (deine Ereignisfunktion TGPuttySFTPClient1SFTPListing), damit die Rezeption (die SFTP-Komponente) dir Bescheid sagen kann, wenn das Taxi da ist (das Listing abgerufen ist). Wenn das Taxi dann ankommt (das Listing da ist), ruft dich die Rezeption (die SFTP-Komponente) unter der hinterlegten Telefonnummer (der Ereignisfunktion) zurück und nennt dir dabei zur Identifikation das Kennzeichen des Taxis (der an die Funktion übergebene Inhalt des Listings).

H.Bothur 21. Apr 2023 16:08

AW: Delphi 10.4 - Indy und SFTP
 
Moin Sebastian,

vielen Dnak für die Infos und deine Mühe !!! ... ich versuche das morgen mal in Source umzusetzen und zu kucken ob ich das hinbekomme.

Gruss
Hans

H.Bothur 27. Apr 2023 16:14

AW: Delphi 10.4 - Indy und SFTP
 
Moin,

sorry das ich jetzt erst weitermache - aber die letzten Tage habe ich es nicht geschafft.

Nur damit ich das richtig sehe ... im Source der Demo finde ich folgende Stelle:

Delphi-Quellcode:
procedure TVCLSFTPClientDemoForm.FormCreate(Sender: TObject);
begin
  PSFTP:=TTGPuttySFTP.Create(true);
  PSFTP.OnListing:=ListingCallback;
  PSFTP.OnMessage:=MessageCallback;
  PSFTP.OnProgress:=ProgressCallback;
  PSFTP.OnGetInput:=GetInputCallback;
  PSFTP.OnVerifyHostKey:=VerifyHostKeyCallback;
end;
Hier wird also einmal das Objekt "PSFTP" erzeugt und für die verschiedenen Ereignisse (OnListing / OnMessage / OnProgress) jeweils definiert welche Procedure dann aufgerufen wird ?

Sorry wenn ich so doff Frage aber das ist nicht mehr dieses "von-oben-nach-unten"-Programmieren das ich aus den 80ern kenne :-)

Gruss
Hans

H.Bothur 27. Apr 2023 17:11

AW: Delphi 10.4 - Indy und SFTP
 
Liste der Anhänge anzeigen (Anzahl: 1)
Soo .. und trotzdem verwirrt mich alles - es passiert folgendes: Ich habe jetzt ein Programm das sich kompilieren lässt und dann den Connect sauber hinbekommt.

Delphi-Quellcode:
unit SFTPUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, tgputtylib, tgputtysftp,
  Vcl.Grids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    InfoLB: TListBox;
    RemoteFilesSG: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
    TestSFTP :TTGPuttySFTP;
    function onVerifyHostKey(const host:PAnsiChar;const port:Integer; const fingerprint:PAnsiChar; const verificationstatus:Integer; var storehostkey:Boolean): Boolean;
    procedure Verbinden;
    procedure Trennen;
    procedure DatenAbruf;

  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  Username = 'name';
  Passwort = 'passwort';
  Host = 'ssh.strato.de';
  Port = 22;

function TForm1.onVerifyHostKey(const host: PAnsiChar; const port: Integer; const fingerprint: PAnsiChar; const verificationstatus: Integer; var storehostkey: Boolean): Boolean;
(* Verhindert einen Abbruch bei Connect *)
begin
  storeHostKey := true;
end;

procedure TForm1.Verbinden;
begin
  TestSFTP.HostName := Host;
  TestSFTP.UserName := UserName;
  TestSFTP.Password := Passwort;
  TestSFTP.Port := Port;
  TestSFTP.OnVerifyHostKey := onVerifyHostkey;
  try
    TestSFTP.Connect;
  except
    on E:Exception do WriteLn('EXCEPTION: ',E.Message);
  end;
  if TestSFTP.Connected then Form1.InfoLB.Items.Insert(0, 'Angeblich verbunden :-)');
end;

procedure TForm1.Trennen;
begin
  TestSFTP.Disconnect;
end;

procedure TForm1.DatenAbruf;
begin
  RemoteFilesSG.RowCount:=1;
  RemoteFilesSG.ColCount:=3;
  RemoteFilesSG.ColWidths[0]:=480;
  RemoteFilesSG.ColWidths[1]:=300;
  RemoteFilesSG.ColWidths[2]:=150;
  RemoteFilesSG.Cells[0,0]:='Name';
  RemoteFilesSG.Cells[1,0]:='Timestamp';
  RemoteFilesSG.Cells[2,0]:='Size';
  TestSFTP.ListDir('');
  if RemoteFilesSG.RowCount>1 then RemoteFilesSG.FixedRows:=1;
  RemoteFilesSG.FixedCols:=0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TestSFTP := TTGPuttySFTP.Create(true);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Button1.Caption = 'Start' then
  begin
    Verbinden;
    Button1.Caption := 'Ende';
  end else
  begin
    Trennen;
    Application.Terminate;
  end;
end;

end.
Und dann passiert was ganz komisches:

Ich füge im Interface unter
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    InfoLB: TListBox;
    RemoteFilesSG: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
[B]   function TGPuttySFTPClient1SFTPListing(Sender: TObject; const Items: TSFTPItems): Boolean;[/B]
  private
die Funktion für das Listing ein - da wird dann im Compiler nur die Function unterschrieben - klar, ungenügende Forward-Deklaration - aber dann.


Dann füge ich im implementations-Teil die Funktion selber ein:

Delphi-Quellcode:
function TForm1.TGPuttySFTPClient1SFTPListing(Sender: TObject; const Items: TSFTPItems): Boolean;
var StartRow,i:Integer;
begin
  StartRow:=RemoteFilesSG.RowCount;
  RemoteFilesSG.RowCount:=StartRow+Length(Items);
  for i:=0 to Length(Items)-1 do begin
    RemoteFilesSG.Cells[0,StartRow+i]:=Items[i].filename;
    RemoteFilesSG.Cells[1,StartRow+i]:=DateTimeToStr(TTimeZone.Local.ToLocalTime(UnixToDateTime(Items[i].attrs.mtime)));
    if Items[i].attrs.permissions and $F000 = $4000 then
       sgRemoteFiles.Cells[2,StartRow+i]:='<dir>'
    else
       sgRemoteFiles.Cells[2,StartRow+i]:=IntToStr(Items[i].attrs.size);
    end;
  Result:=true;
end;
Da werden dann aber - neben Fehlern in der procedure selber - plötzlich auch im Interface Button1Click und FormCreate unterstrichen. Und auch die Proceduren Verbinden, Trennen und DatenAbruf werden als unbekannt markiert !

Und nun stehe ich da mit meiner Weißheit und verzweifle nur noch.

Vielleicht mag sich das jemand mal ansehen der mehr davon versteht - ich weiß nicht wieso das passiert. Ich hab mal den ganzen Ordner als ZIP angehängt.

Gruss
Hans

H.Bothur 28. Apr 2023 18:09

AW: Delphi 10.4 - Indy und SFTP
 
Moin,

nur noch einmal zu der function TForm1.TGPuttySFTPClient1SFTPListing(Sender: TObject; const Items: TSFTPItems): Boolean;

wenn ich da den Code rausnehme und nur noch

Delphi-Quellcode:
function TForm1.TGPuttySFTPClient1SFTPListing(Sender: TObject; const Items: TSFTPItems): Boolean;
var StartRow,
    i:Integer;
begin
  Result:=true;
end;
stehen lasse dann verschwinden die ganzen Fehlermeldungen ?! :shock::shock::shock:
Vielleicht kennt ja jemand dieses Verhalten.

Gruss
Hans

jaenicke 2. Mai 2023 17:53

AW: Delphi 10.4 - Indy und SFTP
 
Ich habe deine Antworten erst jetzt gesehen. Fällt dir wirklich nichts auf an deiner Einrückung (siehe Kommentar)?
Delphi-Quellcode:
function TForm1.TGPuttySFTPClient1SFTPListing(Sender: TObject; const Items: TSFTPItems): Boolean;
var StartRow,i:Integer;
begin
  StartRow:=RemoteFilesSG.RowCount;
  RemoteFilesSG.RowCount:=StartRow+Length(Items);
  for i:=0 to Length(Items)-1 do begin // <-- hier ist ein begin, aber wo ist das end?
    RemoteFilesSG.Cells[0,StartRow+i]:=Items[i].filename;
    RemoteFilesSG.Cells[1,StartRow+i]:=DateTimeToStr(TTimeZone.Local.ToLocalTime(UnixToDateTime(Items[i].attrs.mtime)));
    if Items[i].attrs.permissions and $F000 = $4000 then
       sgRemoteFiles.Cells[2,StartRow+i]:='<dir>'
    else
       sgRemoteFiles.Cells[2,StartRow+i]:=IntToStr(Items[i].attrs.size);
    end;
  Result:=true;
end;
Deshalb ist es äußerst schlechter Coding Style, wenn man das begin hinten an eine Zeile anhängt oder bei if..then in der gleichen Zeile weitermacht. Man übersieht es so viel zu leicht. Ein Befehl pro Zeile.

Ja, ich habe gesehen, dass du das beim begin ansonsten auch so gemacht hast. ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:00 Uhr.
Seite 4 von 4   « Erste     234   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz