Hallo,
wenn ihr bloß ein File per SFTP verschicken wollt, könnt ihr das Programm
PSCP von den Putty-Programmen verwenden.
Ich habe einen Beispielcode weiter unten. Es war nur mal ein Test und ist deswegen
nicht ganz sauber programmiert was die Statusausgaben betrifft
Ihr braucht ein Editfeld für den Status und ein Memofeld für die Fehler.
Als erstes die Copy funktion:
Delphi-Quellcode:
function TForm1.SftpCopy(const Command: String; var Errors: TStringList): Boolean;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
SecurityAttr: TSecurityAttributes;
PipeOutputRead: THandle;
PipeOutputWrite: THandle;
PipeErrorsRead: THandle;
PipeErrorsWrite: THandle;
Succeed: Boolean;
Buffer: array [0..255] of Char;
NumberOfBytesRead: DWORD;
Stream: TMemoryStream;
begin
//Initialisierung ProcessInfo
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
//Initialisierung SecurityAttr
FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
SecurityAttr.nLength := SizeOf(SecurityAttr);
SecurityAttr.bInheritHandle := true;
SecurityAttr.lpSecurityDescriptor := nil;
//Pipes erzeugen
CreatePipe(PipeOutputRead, PipeOutputWrite, @SecurityAttr, 0);
CreatePipe(PipeErrorsRead, PipeErrorsWrite, @SecurityAttr, 0);
//Initialisierung StartupInfo
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb:=SizeOf(StartupInfo);
StartupInfo.hStdInput := 0;
StartupInfo.hStdOutput := PipeOutputWrite;
StartupInfo.hStdError := PipeErrorsWrite;
StartupInfo.wShowWindow := sw_Hide;
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
if CreateProcess(nil, PChar(command), nil, nil, true,
CREATE_DEFAULT_ERROR_MODE or CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil,
StartupInfo, ProcessInfo) then begin
result:=true;
//Write-Pipes schließen
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsWrite);
//Ausgabe Read-Pipe auslesen
try
while true do begin
succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
if not succeed then break;
//zyklische Ausgabe des Status der Übertragung
edit1.Text:=Trim(buffer);
edit1.repaint;
buffer:='';
end;
finally
end;
CloseHandle(PipeOutputRead);
//Fehler Read-Pipe auslesen
Stream := TMemoryStream.Create;
try
while true do begin
succeed := ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil);
if not succeed then break;
Stream.Write(Buffer, NumberOfBytesRead);
buffer:='';
end;
Stream.Position := 0;
Errors.LoadFromStream(Stream);
finally
Stream.Free;
end;
CloseHandle(PipeErrorsRead);
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hProcess);
end
else begin
result:=false;
CloseHandle(PipeOutputRead);
CloseHandle(PipeOutputWrite);
CloseHandle(PipeErrorsRead);
CloseHandle(PipeErrorsWrite);
end;
end;
Und dann der Aufruf vom Programm
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var errors: TStringList;
begin
try
errors:=TStringList.Create;
if SftpCopy('pscp -C -l user -pw Password d:\testfile host:/home', errors) then
Memo1.Lines.Assign(errors);
finally
errors.free;
end;
end;
Es soll also D:\Testfile nach host:/home kopiert werden. -C heißt aktiviere Kompression,
user und password sind klar. Wenn sich PSCP nicht im selben Pfad wie Eure Anwendung befindet,
müßt ihr diesen mit angeben. (z.B.: d:\putty\pscp)
Wenn ich Zeit habe, packe ich das ganze mal in eine Komponente, damit man das ordentlich
bedienen kann.
So denn
Daliuz