Autor |
Beitrag |
MarkusBauer
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 16:08
Hallo
ich habe eine DLL geschrieben, die über einen TrivialFTP-Server Daten empfangen bzw. versenden und sich anschließend beenden soll. Das Ganze soll ohne ein Formular stattfinden. Allerdings muss die Prozedur dazu auf das Ende der Übertragung abwarten. Hier der Code:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| type TTFTP = class ftp: TIdTrivialFTPServer; procedure FTPInit(port: Integer); procedure IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); procedure IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); procedure IdTrivialFTPServer1WriteFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); end;
var server: TTFTP; terminate: Boolean;
procedure Run; stdcall; begin terminate := false; server := TTFTP.Create; server.FTPInit(port); while not terminate do begin sleep(50); end; end;
procedure TTFTP.IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation: Boolean); begin try If Assigned(AStream) then FreeAndNil(AStream); except end; showmessage('done'); terminate := true; end;
procedure TTFTP.FTPInit(port: Integer); begin ftp := tIdTrivialFTPServer.create( nil ) ; ftp.DefaultPort := port; ftp.ThreadedEvent := true; ftp.OnReadFile := IdTrivialFTPServer1ReadFile; ftp.OnTransferComplete := IdTrivialFTPServer1TransferComplete; ftp.Active := true; end;
exports Run; |
Die Datei wird zwar komplett übertragen, allerdings wird die TransferComplete-Routine nicht aufgerufen, die Anwendung läuft auch nach der Übertragung weiter. Dies liegt wohl an der Warteschleife (while not terminate do...), wenn ich statt dieser die auskommentierte showmessage-Funktion benutze funktioniert alles.
Gibt es eine Möglichkeit auf das Ende der Aktion zu warten, ohne das komplette Programm lahmzulegen?
Danke
Markus
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 17:14
Hi, ich bin mir nicht sicher, aber Du setzt terminate auf false
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure Run; stdcall; begin terminate := false; server := TTFTP.Create; server.FTPInit(port); while not terminate do begin sleep(50); end; end; |
und prüfst terminate auf false
soll das so sein?
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 17:18
ja das sollte so sein. terminate gibt an, ob die Anwendung beendet werden soll.
Die Schleife soll so lange laufen, wie das Programm noch nicht beendet werden soll. In der TransferComplete-Routine sollte terminate auf true gesetzt werden, dann sollte die Schleife beenden. So wars zumindest gedacht ...
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 17:39
mh..wo rufst Du denn die procedure TTFTP.IdTrivialFTPServer1TransferComplete(Sender: TObject;....) auf?
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 17:49
Delphi-Quelltext 1:
| ftp.OnTransferComplete := IdTrivialFTPServer1TransferComplete; |
Die Routine sollte vom TrivialFTPServer aufgerufen werden, wenn er seine Arbeit beendet hat.
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 17:59
sorry hab es übersehen mhh.., bei den langen Procedure namen brauch man ne weile
Wie sieht den die Procedure IdTrivialFTPServer1ReadFile aus?
Wenn Du sagst, das es gar nicht bis zum Aufruf von IdTrivialFTPServer1TransferComplete kommt!
heist also, die Meldung aus der Proc -showmessage('done')- kommt also auch nicht!?
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Di 11.05.10 18:13
Probier mal bitte folgendes:
Delphi-Quelltext 1: 2: 3: 4: 5:
| while not terminate do begin Application.ProcessMessages; sleep(50); end; |
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 19:06
Die Prozedur sieht so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TTFTP.IdTrivialFTPServer1ReadFile(Sender: TObject; var FileName: String; const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete: Boolean); var FS : TFileStream; begin FreeStreamOnComplete := True; try if uppercase(Filename) = uppercase(extractfilename(f)) then begin FS := TFileStream.Create(f, fmOpenRead or fmShareDenyWrite); AStream := FS; GrantAccess := True; end else begin GrantAccess := False; end; except GrantAccess := False; If Assigned(FS) then FreeAndNil( FS ); end; end; |
Also showmessage('done') kommt nicht, aber die Datei wird komplett übertragen. Ich vermute dass das Transfer-Complete-Event nicht abgearbeitet wird da die Warteschleife noch alle Ressourcen belegt.
Application.ProcessMessages bringt keinen Unterschied, auch nicht wenn ich vor Application.Initialize; und Application.Run; ausführe.
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 11.05.10 19:15
((und jetzt nimm' noch das sleep raus. Busy waiting sollte ja nicht besser sein, als die Ganze Zeit auf Fensterbefehle zu reagieren))
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 19:30
Ohne Sleep bringt keine Änderungen, außer dass die CPU voll ausgelastet wird. Application.ProcessMessages scheint nichts zu bringen, da die Anwendung kein Formular hat (Konsolenanwendung ohne {APPTYPE: CONSOLE}).
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 19:58
MarkusBauer hat folgendes geschrieben : | Ich vermute dass das Transfer-Complete-Event nicht abgearbeitet wird... |
Das ist ja schon bekannt! Aber woher erhälts Du die info, das die Datei übertragen wurde?
nur so macht es sinn die Proc IdTrivialFTPServer1TransferComplete überhaupt aufzurufen!
So wie es aussieht, ohne slepp, nur mit showmessage-Funktion funct es doch, laut Deiner ertsen Aussage!
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 20:23
Die Info erhalte ich dadurch, dass die Datei nach dem Vorgang vollständig und korrekt im Zielverzeichnis liegt. Ja, wenn ich statt der Sleep-Routine die Showmessage-Box nutze funktionierts, allerdings kann ich dem Nutzer schlecht eine MessageBox mit "bitte drücken sie hier, wenn alles abgeschlossen ist" präsentieren.
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 20:54
MarkusBauer hat folgendes geschrieben : | Die Info erhalte ich dadurch, dass die Datei nach dem Vorgang vollständig und korrekt im Zielverzeichnis liegt. |
Aber doch nicht als Rückgabe für Deine Procedure!
Wie willst Du sonst die kontrolle haben (Protokoll)?
Warum lässt Du die Message nicht einfach weg!
Legst ne logfile zur kontrolle an. mhh.. solltest Du vielleicht mit einbauen falls irgenwo was schief geht!
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
MarkusBauer 
      
Beiträge: 70
Win XP Pro
Delphi 7 PE+Indy
|
Verfasst: Di 11.05.10 21:34
Die Prozedur wird ja auch nicht von mir, sondern von der TTrivialFTP-Komponente aufgerufen. Die Message brauch ich nur, damit sich das Programm beendet, nachdem die Datei übertragen wurde, ob das Ganze erfolgreich war oder nicht ist eigentlich unwichtig. Gibts vllt. ne andere Art das Programm nach der Übertragung zu beenden?
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 11.05.10 21:43
Hast Du Dir das angeschaut en.wikipedia.org/wik...le_Transfer_Protocol oder de.wikipedia.org/wik...le_Transfer_Protocol
Das meint ich mit Protokoll, damit sollte doch ne vernünftige Rückmeldung zu erfahren sein, die Du mit einbaust um Deine DLL zu entladen Proc zu beenden!
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|