Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14
  1. #1
    Forenclown Avatar von cl9wn
    Registriert seit
    27.07.2008
    Beiträge
    599

    Standard Indy FTP Client problem!!!

    Hi, ich wollte mir mal einen kleinen FTP Client basteln. Connecten kann ich schon, disconnecten auch aber bei der Auflistung der ORdnerstruktur und der Dateien ist es vorbei.

    Quellcode bisher:

    Code:
    unit StealerFTPParasite;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
      IdTCPClient, IdExplicitTLSClientServerBase, IdFTP, FileCtrl;
    
    type
      TfrmMain = class(TForm)
        editFTPHost: TEdit;
        editFTPUsername: TEdit;
        lblFTPHost: TLabel;
        lblFTPUsername: TLabel;
        editFTPPassword: TEdit;
        lblFTPPassword: TLabel;
        btnConnect: TButton;
        btnDisconnect: TButton;
        IdFTP1: TIdFTP;
        DirectoryListBox1: TDirectoryListBox;
        procedure btnConnectClick(Sender: TObject);
        procedure btnDisconnectClick(Sender: TObject);
        procedure IdFTP1Connected(Sender: TObject);
        procedure IdFTP1Disconnected(Sender: TObject);
      private
        { Private-Deklarationen }
      public
        { Public-Deklarationen }
      end;
    
    var
      frmMain: TfrmMain;
    
    implementation
    
    {$R *.dfm}
    
    procedure TfrmMain.btnConnectClick(Sender: TObject);
    begin
      IdFTP1.Host := editFTPHost.Text;
      IdFTP1.UserName := editFTPUsername.Text;
      IdFTP1.Password := editFTPPassword.Text;
      IdFTP1.Connect;
    end;
    
    procedure TfrmMain.btnDisconnectClick(Sender: TObject);
    begin
      if IdFTP1.Connected = False then
        MessageBox(Self.Handle,'Not connected to FTP Server','Could not disconnect from FTP',mrNone)
      else
        begin
          IdFTP1.Quit;
        end;
    end;
    
    procedure TfrmMain.IdFTP1Connected(Sender: TObject);
    begin
    showmessage('Connected to ' + editFTPHost.Text);
    IdFTP1.List(DirectoryListBox1.Items,'*.*',FALSE);
    end;
    
    procedure TfrmMain.IdFTP1Disconnected(Sender: TObject);
    begin
    showmessage('Disconnected from ' + editFTPHost.Text)
    end;
    
    end.
    Wenn ich es so ausführe, wie ich es hier gepostet habe, kommt ein Error:

    Please login with USER and PASS
    Wenn ich die Zeile "IdFTP1.List(DirectoryListBox1.Items,'*.*',FALSE); " aus dem Quellcode entferne, verschwindet der Error.

    Was zum Teufel ist das? Ich logge mich doch mit Username und Passwort ein... Wer kann helfen?

  2. #2

    Registriert seit
    17.06.2009
    Beiträge
    559

    Standard

    Entweder du stellst die Eigenschaft AutoLogin auf true oder du rufst nach einer erfolgten Verbindung einmal die Methode Login auf.
    (Ein einfaches Connect stellt nur die Verbindung her, loggt sich aber nicht ein.)

  3. #3
    Forenclown Avatar von cl9wn
    Registriert seit
    27.07.2008
    Beiträge
    599

    Standard

    AutoLogin steht auf true O.o

  4. #4

    Registriert seit
    17.06.2009
    Beiträge
    559

    Standard

    Nimm das List mal aus dem Connect-Event raus und versuchs mal so
    Code:
    begin
      IdFTP1.Host := editFTPHost.Text;
      IdFTP1.UserName := editFTPUsername.Text;
      IdFTP1.Password := editFTPPassword.Text;
      IdFTP1.AutoLogin := True;
      try
        IdFTP1.Connect;
        IdFTP1.List(DirectoryListBox1.Items,'*.*',FALSE);
      except
        on E: Exception do ShowMessage(E.Message);
      end;
    end;

  5. #5
    Forenclown Avatar von cl9wn
    Registriert seit
    27.07.2008
    Beiträge
    599

  6. #6

    Registriert seit
    17.06.2009
    Beiträge
    559

    Standard

    Das ist ein Bug, der ab Delphi 2005 (oder 2006?) auftritt.
    Du kannst dir entweder die neueste Indy Version (Tiburon) installieren oder dir mit diesem Code aushelfen:
    Code:
    uses IdAllFTPListParsers;
    [...]
    var
      I: Integer;
    begin
      IdFTP1.Host := editFTPHost.Text;
      IdFTP1.UserName := editFTPUsername.Text;
      IdFTP1.Password := editFTPPassword.Text;
      IdFTP1.AutoLogin := True;
      try
        IdFTP1.Connect;
        IdFTP1.List;
        for I := 0 to Pred(IdFTP1.DirectoryListing.Count) do
          DirectoryListBox1.Items.Add(IdFTP1.DirectoryListing[I].FileName);  
      except
        on E: Exception do ShowMessage(E.Message);
      end;
    end;

  7. #7
    Forenclown Avatar von cl9wn
    Registriert seit
    27.07.2008
    Beiträge
    599

    Standard

    ich hab delphi 2009, ist das neuste Indy da nicht schon dabei? Falls nicht, hast du vllt. einen Link mit Download + Anleitung zur Installation?

  8. #8

    Registriert seit
    17.06.2009
    Beiträge
    559

    Standard

    Ich glaube bei D2009 ist die aktuellste Stable Version (10.2.5) dabei, aber eben nicht die neueste.
    Die neueste bekommst du hier. Allerdings ohne Auto-Installer, muss also selber kompiliert und installiert werden. Eine Anleitung sollte mit dabei sein.

    ---
    Wieso lässt du Indys nicht einfach komplett weg und machst es mit der Wininet-API?
    Das ist genauso einfach, wenn nicht sogar noch einfacher und du bist damit viel flexibler und kannst dich darauf auch verlassen.
    Gerade mit D2009 und Unicode gibt es bei den ganzen Socket Sachen häufig Probleme.

  9. #9
    Forenclown Avatar von cl9wn
    Registriert seit
    27.07.2008
    Beiträge
    599

    Standard

    Also vielleicht sollte ich näher beschreiben was ich will:

    Ich brauche eigentlich nur auf den FTP zu connecten, mich einzuloggen und dann eine Liste der Dateinamen und deren Erstellungs-/änderungsdatum auslesen und speichern, um sie dann beim nächsten programmstart wieder zu vergleichen, ob was neues dazugekommen ist.

    Also brauche ich eigentlich keine ganze File-Anzeige die mir alles auflistet sondern ich brauche nur Filename und Datum...

    Was wäre da die beste Möglichkeit?

  10. #10

    Registriert seit
    17.06.2009
    Beiträge
    559

    Standard

    So, hab da mal kurz was gebastelt:
    Code:
    uses
      WinInet;
    
    type
      TFTPFilesRec = record
        FileName: string;
        FileSize: Int64;
        CreationTime, LastAccessTime, LastWriteTime: FileTime;
        Attributes: Cardinal;
      end;
      TFTPFiles = Array of TFTPFilesRec;
    
    function GetFTPFileList(const AHost, AUsername, APassword, ADirectory: string;
      var AFTPFiles: TFTPFiles): Boolean;
    var
      hOpen, hConnect, hFind: HINTERNET;
      FindData: WIN32_FIND_DATA;
      iCounter: Integer;
    begin
      Result := False;
      hOpen := InternetOpen(nil, INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
      if Assigned(hOpen) then try
        hConnect := InternetConnect(hOpen, PChar(AHost), INTERNET_DEFAULT_FTP_PORT,
          PChar(AUsername), PChar(APassword), INTERNET_SERVICE_FTP,
            INTERNET_FLAG_PASSIVE, 0);
        if Assigned(hConnect) then try
          hFind := FtpFindFirstFile(hConnect, PChar(ADirectory), FindData,
            INTERNET_FLAG_RELOAD, 0);
          if Assigned(hFind) then try
            iCounter := 0;
            repeat
              if FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <>
                FILE_ATTRIBUTE_DIRECTORY then
              begin
                SetLength(AFTPFiles, Succ(iCounter));
                with AFTPFiles[iCounter], FindData do
                begin
                  FileName := cFileName;
                  FileSize := nFileSizeHigh * MAXDWORD + nFileSizeLow;
                  CreationTime := ftCreationTime;
                  LastAccessTime := ftLastAccessTime;
                  LastWriteTime := ftLastWriteTime;
                  Attributes := dwFileAttributes;
                end;
                Inc(iCounter);
              end;
            until not InternetFindNextFile(hFind, @FindData);
            Result := True;
          finally
            InternetCloseHandle(hFind);
          end;
        finally
          InternetCloseHandle(hConnect);
        end;
      finally
        InternetCloseHandle(hOpen);
      end;
    end;
    Diese Funktion erstellt dir deine Dateiliste bzw. Array mit allen möglichen Informationen. Sie listet nur Dateien auf und arbeitet nicht rekursiv, sie behandelt also nur das angegebene Verzeichnis und nicht deren Unterordner. Das könnte man noch ändern, aber dann wäre der Code ein wenig komplexer, ich denke so reicht es.

    Möglicher Aufruf:
    Code:
    var
      I: Integer;
      A: TFTPFiles;
    begin
      if GetFTPFileList('ftp.microsoft.com', 'anonymous', 'somepass', 'bussys', A) then
        for I := Low(A) to High(A) do
          ShowMessage(A[I].FileName + ' ' + IntToStr(A[I].FileSize));
    end;
    (leerer Ordner == Stammverzeichnis)

    Du könntest nun beim Programmstart eine globale Dateiliste bzw. Array damit anlegen und dann z.B in einem bestimmten Intervall eine neue anlegen und beide dann vergleichen. Ich denke, dass mit dem Vergleichen bekommst du auch selber hin, ist ja nur eine bzw. zwei Schleife(n).

    Ich hoffe das hilft dir nun ein wenig.
    Geändert von inout (08.08.2009 um 00:45 Uhr)

Seite 1 von 2 12 LetzteLetzte

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •