Ja, auch das geht mit NAV! Allerdings ist Siherunterladencherheit ein nicht ganz so groß geschriebenes Wort an dieser Stelle. Verwendet wird die von ftp.exe von Microsoft. Hierfür kann prinzipiell eine Konfigurationsdatei erstellt werden und per Console (Ausführen –> cmd) ausgeführt werden. Das bedeutet für uns, dass wir dies in NAV auch nutzen können.
Die Idee
Wir erstellen eine Konfigurations-Datei und verwenden diese direkt per ftp.exe in kombination mit der Console.
Voraussetzungen
Wir benötigen also Benutzername, Passwort, Hostname und Dateiname der zu herrunterladenenen Datei sowie der Pfad, wo diese hingespeichert werden soll.
Die Umsetzung
Wir erstellen eine Codeunit die dafür zuständig ist, Dateien von einem FTP Server herrunter zu laden. Dieser verbindet sich mit einem Benutzerkonto auf einen FTP Server und lädt eine Datei in ein ausgewählten Pfad. In der Codeunit gibt es folgende Funktionen:
- setHideDialog – Dialogbox ein bzw. auschalten.
- XENVIRON – Umgebungsvariable abrufen, wird verwendet um die Konfigurationsdatei in den TEMPORARAYPATH zu sichern.
- FileExists – Kontrolle ob eine Datei schon existiert. Wichtig für Timeout!
- getFTPData – Daten vom FTP abrufen.
Der Quellcode
Hier der exportierte AL-Code als Textexport:
OBJECT Codeunit 50008 FTP Data { OBJECT-PROPERTIES { Date=01.09.10; Time=12:57:38; Modified=Yes; Version List=; } PROPERTIES { OnRun=BEGIN getFTPData('Matt', '*1*2*3*4', 'irgendeinFTP.de/', 'c:/temp/', 'Test.zip'); END; } CODE { VAR HideDialog@1000000000 : Boolean; PROCEDURE setHideDialog@1000000002(value@1000000000 : Boolean); BEGIN HideDialog := value; END; PROCEDURE XENVIRON@1000000001(Value@1000000000 : Text[50]) : Text[1024]; VAR WshShell@1000000001 : Automation "{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{72C24DD5-D70A-438B-8A42-98424B88AFB8}:'Windows Script Host Object Model'.WshShell"; BEGIN // Webservices and RTC IF ISSERVICETIER THEN BEGIN CREATE(WshShell, TRUE, TRUE); EXIT( WshShell.ExpandEnvironmentStrings('%' + Value + '%') ); END ELSE BEGIN EXIT( ENVIRON(Value) ); END; END; PROCEDURE FileExists@1140002(Foldername@1140000 : Text[256]) : Boolean; VAR FileSystemObject@50000 : Automation "{420B2830-E718-11CF-893D-00A0C9054228} 1.0:{0D43FE01-F093-11CF-8940-00A0C9054228}:'Microsoft Scripting Runtime'.FileSystemObject"; BEGIN IF ISCLEAR(FileSystemObject) THEN CREATE(FileSystemObject, TRUE, TRUE); EXIT(FileSystemObject.FileExists(Foldername)); END; PROCEDURE getFTPData@1000000000(UsernameValue@1000000025 : Text[250];PasswordValue@1000000026 : Text[250];HostAddressValue@1000000027 : Text[1024];DestPathValue@1000000028 : Text[1024];FileNameValue@1000000029 : Text[1024]); VAR CommandsFile@1000000000 : File; MSShell@1000000018 : Automation "{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{72C24DD5-D70A-438B-8A42-98424B88AFB8}:'Windows Script Host Object Model'.WshShell"; FileSystemObject@1000000017 : Automation "{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{0D43FE01-F093-11CF-8940-00A0C9054228}:'Windows Script Host Object Model'.FileSystemObject"; WindowStyle@1000000006 : Variant; WaitOnReturn@1000000005 : Variant; DateText@1000000024 : Text[8]; MemberNo@1000000023 : Text[6]; HostAddress@1000000022 : Text[1024]; CommandsFileTxt@1000000021 : Text[1024]; FileName@1000000019 : Text[1024]; DestinationFilePath@1000000015 : Text[1024]; Password@1000000009 : Text[250]; UserName@1000000008 : Text[250]; sleepIndex@1000000004 : Integer; maxTimeOutMilSec@1000000003 : Integer; maxTimeOut@1000000002 : Integer; timeOut@1000000001 : Integer; dlg@1000000007 : Dialog; BEGIN // ############################################################################################################################### // Parameter // ############################################################################################################################### // Datei mit KLARTEXT Einlogg-Daten CommandsFileTxt := XENVIRON('TEMP') + '\__TEMP__984613516~65435164.txt'; maxTimeOutMilSec := 60000; // 60 Sekunden Timout // Zugangsdaten UserName := UsernameValue; Password := PasswordValue; HostAddress := HostAddressValue; DestinationFilePath := DestPathValue; FileName := FileNameValue; // ############################################################################################################################### // Timeout-Berechnung maxTimeOut := maxTimeOutMilSec / 500; IF (maxTimeOutMilSec = 0) AND (maxTimeOut = 0) THEN BEGIN maxTimeOutMilSec := 10000; maxTimeOut := maxTimeOutMilSec / 500; END; IF NOT HideDialog THEN BEGIN dlg.OPEN('Datei wird abgerufen #1###################\'+ 'Status #2###################\'+ 'Timeout #3###################'); dlg.UPDATE(1, FileName); dlg.UPDATE(2, 'Anfrage wird erstellt'); END; IF ISCLEAR(MSShell) THEN CREATE(MSShell); IF ISCLEAR(FileSystemObject) THEN CREATE(FileSystemObject); CommandsFile.TEXTMODE(TRUE); CommandsFile.WRITEMODE(TRUE); // Wenn die Datei nicht erstellt werden kann, muss diese erst gel”st werden (noch existent) IF NOT CommandsFile.CREATE(CommandsFileTxt) THEN BEGIN // Prozess Beenden, falls noch im Zugriff // MSShell.ShellExecute('cmd', '/c TASKKILL /F /IM FTP.EXE /T', '', '', 0 ); MSShell.Exec('/c TASKKILL /F /IM FTP.EXE /T'); FileSystemObject.DeleteFile(CommandsFileTxt, TRUE); CommandsFile.CREATE(CommandsFileTxt) END; CommandsFile.WRITE(UserName); CommandsFile.WRITE(Password); CommandsFile.WRITE('binary'); CommandsFile.WRITE('get ' + FileName+ ' "' + DestinationFilePath + '"' ); CommandsFile.WRITE('quit'); CommandsFile.TRUNC; CommandsFile.CLOSE; // MESSAGE('%1', STRSUBSTNO('ftp -s:"%1" %2', CommandsFileTxt, HostAddress)); // ERROR(''); // Abruf! Request! WindowStyle := 0; // nicht sichtbar WaitOnReturn := FALSE; // asynchron // An dieser Stelle wird die Datei aufgegriffen und mit ftp.exe verwendet MSShell.Run(STRSUBSTNO('ftp -s:"%1" %2', CommandsFileTxt, HostAddress), WindowStyle, WaitOnReturn); // wait for it! TimeOut! REPEAT IF NOT HideDialog THEN BEGIN // kein "flackern" dlg.UPDATE(2, ''); dlg.UPDATE(2, 'Warte auf Antwort'); END; SLEEP(500); timeOut += 1; IF NOT HideDialog THEN BEGIN // kein "flackern" dlg.UPDATE(3, ''); dlg.UPDATE(3, (500 * timeOut) / 1000); END; UNTIL (FileExists(DestinationFilePath)) OR (timeOut = maxTimeOut); // Datei erhalten IF (timeOut <> maxTimeOut) THEN BEGIN IF NOT HideDialog THEN BEGIN dlg.UPDATE(2, ''); dlg.UPDATE(2, 'Antwort erhalten!'); // zur Darstellung SLEEP(1000); END; END ELSE BEGIN // keine Datei erhalten IF NOT HideDialog THEN BEGIN dlg.UPDATE(2, ''); dlg.UPDATE(2, 'Antwort nicht erhalten!'); // zur Darstellung SLEEP(1000); END; END; // Datei sicherheitshalber l”schen, Loggindaten im Klartext enthalten IF FileExists(CommandsFileTxt) THEN BEGIN // MSShell.Exec('/c TASKKILL /F /IM FTP.EXE /T'); FileSystemObject.DeleteFile(CommandsFileTxt, TRUE); END; IF NOT HideDialog THEN dlg.CLOSE; END; BEGIN END. } }
Falls sich hier der Fehlerteufel eingeschlichen hat, bitte ich um ein Kommentar 🙂
Gruß,
Matthias König
{
OBJECT-PROPERTIES
{
Date=01.09.10;
Time=12:57:38;
Modified=Yes;
Version List=;
}
PROPERTIES
{
OnRun=BEGIN
getFTPData(‚Matt‘, ‚*1*2*3*4‘, ‚irgendeinFTP.de/‘, ‚c:/temp/‘, ‚Test.zip‘);
END;}
CODE
{
VAR
HideDialog@1000000000 : Boolean;
PROCEDURE setHideDialog@1000000002(value@1000000000 : Boolean);
BEGIN
HideDialog := value;
END;
PROCEDURE XENVIRON@1000000001(Value@1000000000 : Text[50]) : Text[1024];
VAR
WshShell@1000000001 : Automation „{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{72C24DD5-D70A-438B-8A42-98424B88AFB8}:’Windows Script Host Object Model‘.WshShell“;
BEGIN
// Webservices and RTC
IF ISSERVICETIER THEN BEGIN
CREATE(WshShell, TRUE, TRUE);
EXIT( WshShell.ExpandEnvironmentStrings(‚%‘ + Value + ‚%‘) );
END ELSE BEGIN
EXIT( ENVIRON(Value) );
END;
END;
PROCEDURE FileExists@1140002(Foldername@1140000 : Text[256]) : Boolean;
VAR
FileSystemObject@50000 : Automation „{420B2830-E718-11CF-893D-00A0C9054228} 1.0:{0D43FE01-F093-11CF-8940-00A0C9054228}:’Microsoft Scripting Runtime‘.FileSystemObject“;
BEGIN
IF ISCLEAR(FileSystemObject) THEN
CREATE(FileSystemObject, TRUE, TRUE);
EXIT(FileSystemObject.FileExists(Foldername));
END;
PROCEDURE getFTPData@1000000000(UsernameValue@1000000025 : Text[250];PasswordValue@1000000026 : Text[250];HostAddressValue@1000000027 : Text[1024];DestPathValue@1000000028 : Text[1024];FileNameValue@1000000029 : Text[1024]);
VAR
CommandsFile@1000000000 : File;
MSShell@1000000018 : Automation „{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{72C24DD5-D70A-438B-8A42-98424B88AFB8}:’Windows Script Host Object Model‘.WshShell“;
FileSystemObject@1000000017 : Automation „{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} 1.0:{0D43FE01-F093-11CF-8940-00A0C9054228}:’Windows Script Host Object Model‘.FileSystemObject“;
WindowStyle@1000000006 : Variant;
WaitOnReturn@1000000005 : Variant;
DateText@1000000024 : Text[8];
MemberNo@1000000023 : Text[6];
HostAddress@1000000022 : Text[1024];
CommandsFileTxt@1000000021 : Text[1024];
FileName@1000000019 : Text[1024];
DestinationFilePath@1000000015 : Text[1024];
Password@1000000009 : Text[250];
UserName@1000000008 : Text[250];
sleepIndex@1000000004 : Integer;
maxTimeOutMilSec@1000000003 : Integer;
maxTimeOut@1000000002 : Integer;
timeOut@1000000001 : Integer;
dlg@1000000007 : Dialog;
BEGIN
// ###############################################################################################################################
// Parameter
// ###############################################################################################################################
// Datei mit KLARTEXT Einlogg-Daten
CommandsFileTxt := XENVIRON(‚TEMP‘) + ‚\__TEMP__984613516~65435164.txt‘;
maxTimeOutMilSec := 60000; // 60 Sekunden Timout
// Zugangsdaten
UserName := UsernameValue;
Password := PasswordValue;
HostAddress := HostAddressValue;
DestinationFilePath := DestPathValue;
FileName := FileNameValue;
// ###############################################################################################################################
// Timeout-Berechnung
maxTimeOut := maxTimeOutMilSec / 500;
IF (maxTimeOutMilSec = 0) AND (maxTimeOut = 0) THEN BEGIN
maxTimeOutMilSec := 10000;
maxTimeOut := maxTimeOutMilSec / 500;
END;
IF NOT HideDialog THEN BEGIN
dlg.OPEN(‚Datei wird abgerufen #1###################\’+
‚Status #2###################\’+
‚Timeout #3###################‘);
dlg.UPDATE(1, FileName);
dlg.UPDATE(2, ‚Anfrage wird erstellt‘);
END;
IF ISCLEAR(MSShell) THEN
CREATE(MSShell);
IF ISCLEAR(FileSystemObject) THEN
CREATE(FileSystemObject);
CommandsFile.TEXTMODE(TRUE);
CommandsFile.WRITEMODE(TRUE);
// Wenn die Datei nicht erstellt werden kann, muss diese erst gel”st werden (noch existent)
IF NOT CommandsFile.CREATE(CommandsFileTxt) THEN BEGIN
// Prozess Beenden, falls noch im Zugriff
// MSShell.ShellExecute(‚cmd‘, ‚/c TASKKILL /F /IM FTP.EXE /T‘, “, “, 0 );
MSShell.Exec(‚/c TASKKILL /F /IM FTP.EXE /T‘);
FileSystemObject.DeleteFile(CommandsFileTxt, TRUE);
CommandsFile.CREATE(CommandsFileTxt)
END;
CommandsFile.WRITE(UserName);
CommandsFile.WRITE(Password);
CommandsFile.WRITE(‚binary‘);
CommandsFile.WRITE(‚get ‚ + FileName+ ‚ „‚ + DestinationFilePath + ‚“‚ );
CommandsFile.WRITE(‚quit‘);
CommandsFile.TRUNC;
CommandsFile.CLOSE;
// MESSAGE(‚%1‘, STRSUBSTNO(‚ftp -s:“%1″ %2‘, CommandsFileTxt, HostAddress));
// ERROR(“);
// Abruf! Request!
WindowStyle := 0; // nicht sichtbar
WaitOnReturn := FALSE; // asynchron
// An dieser Stelle wird die Datei aufgegriffen und mit ftp.exe verwendet
MSShell.Run(STRSUBSTNO(‚ftp -s:“%1″ %2‘, CommandsFileTxt, HostAddress), WindowStyle, WaitOnReturn);
// wait for it! TimeOut!
REPEAT
IF NOT HideDialog THEN BEGIN
// kein „flackern“
dlg.UPDATE(2, “);
dlg.UPDATE(2, ‚Warte auf Antwort‘);
END;
SLEEP(500);
timeOut += 1;
IF NOT HideDialog THEN BEGIN
// kein „flackern“
dlg.UPDATE(3, “);
dlg.UPDATE(3, (500 * timeOut) / 1000);
END;
UNTIL (FileExists(DestinationFilePath)) OR (timeOut = maxTimeOut);
// Datei erhalten
IF (timeOut <> maxTimeOut) THEN BEGIN
IF NOT HideDialog THEN BEGIN
dlg.UPDATE(2, “);
dlg.UPDATE(2, ‚Antwort erhalten!‘);
// zur Darstellung
SLEEP(1000);
END;
END ELSE BEGIN
// keine Datei erhalten
IF NOT HideDialog THEN BEGIN
dlg.UPDATE(2, “);
dlg.UPDATE(2, ‚Antwort nicht erhalten!‘);
// zur Darstellung
SLEEP(1000);
END;
END;
// Datei sicherheitshalber l”schen, Loggindaten im Klartext enthalten
IF FileExists(CommandsFileTxt) THEN BEGIN
// MSShell.Exec(‚/c TASKKILL /F /IM FTP.EXE /T‘);
FileSystemObject.DeleteFile(CommandsFileTxt, TRUE);
END;
IF NOT HideDialog THEN
dlg.CLOSE;
END;
BEGIN
END.
}
}
Merci!
Da war nur ein kleiner Tacken mit „MSShell.Run“ der mir schon der ganze Zeit fehlte…
Appreciate the recommendation. Will try it out.
After I originally commented I seem to have clicked
the -Notify me when new comments are added- checkbox and
now each time a comment is added I recieve 4 emails
with the same comment. There has to be an easy method you
can remove me from that service? Appreciate it!
Hi,
is now your the problem solved? 😦
I changed something and there was an wordpress update.