![]() |
Ausgabe einer Befehlszeile in eine Datei umleiten
Guten Abend!
Ich möchte aus meinem Delphi-Programm einige Dateien in ein Winrar-Archiv packen. Die Winrar-Befehlszeile rufe ich mit ShellExecuteEx auf. Die Ausgabe von Winrar möchte ich in eine Log-Datei umleiten. Meine Befehlszeile
Delphi-Quellcode:
funktioniert manuell. Beim Aufruf
rar.exe a archiv.rar *.* > log.txt
Delphi-Quellcode:
wird zwar das Archiv erzeugt, die Log-Datei wird aber nicht geschrieben. Wo ist da das Problem?
FillChar(SEInfo, SizeOf(SEInfo), 0);
SEInfo.cbSize := SizeOf(TShellExecuteInfo); with SEInfo do begin fMask := SEE_MASK_NOCLOSEPROCESS; Wnd := Application.Handle; lpFile := PChar('rar.exe'); lpParameters := PChar('a archiv.rar *.* > log.txt'); nShow := 1; end; ShellExecuteEx(@SEInfo); Ich würde aus der Log-Datei hintenrum die Prozentzahl der Fortschrittsanzeige auslesen wollen, da das Packen über zehn Minuten dauert. Aber vielleicht kennt ja jemand eine bessere Methode, ein rar-Pack-Programm mit Fortschrittsanzeige zu schreiben. Vielen Dank schonmal! |
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
|
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
Das kann aber nur entpacken, wenn ich das richtig sehe...
|
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
huch, das ent habe ich mir wohl irgendwie dazu gedichtet, sorry :oops:
|
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
Es ist zwar keine elegante Lösung, aber machs doch über eine Batchdatei ...
- Batchfile temporär erstellen - Batchfile mit Shellexecute starten - Batchfile löschen ... - wenn RAR fertig > Ausgabedatei löschen :hi: Schöne Grüße, Jens |
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
Oder probier's doch mal der Gewalt einer konkreten Pfadangabe:
Statt: rar.exe a archiv.rar *.* > log.txt das: rar.exe a archiv.rar *.* > c:\log.txt oder: rar.exe a archiv.rar *.* >> c:\log.txt Dann kannst du zumindest feststellen, ob die Ausgabeumleitung nach log.txt überhaupt funktioniert hat. |
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
wenn es dir nur darum geht, die ausgabe einer dos-box zu erhalten, kannst du auch folgende funktion benutzen:
(ich weiss leider nicht mehr, woher ich die habe....)
Delphi-Quellcode:
vielleicht hilft dir das ja weiter....
function RunWaitAndCaptureOutput(CommandLine: string; var Output: string): DWord;
const BufSize = 1024; var buf : array[0..BufSize - 1] of char; si : STARTUPINFO; sa : SECURITY_ATTRIBUTES; sd : SECURITY_DESCRIPTOR; //security information for pipes pi : PROCESS_INFORMATION; // newstdin, newstdout, read_stdout : THandle; // write_stdin:THandle; //pipe handles bytes_read : cardinal; bytes_available : cardinal; procedure ZeroBuffer; begin FillChar(Buf, SizeOf(Buf), 0); end; procedure RaiseError(str: string); var n : DWord; begin n := GetLastError; raise EReadError.CreateFmt('%s: %d/0x%x -%s', [Str, n, n, SysErrorMessage(n)]); //raise ERedirectorError.CreateFmt('%s: %d/0x%x -%s',[Str,n,n,SysErrorMessage(n)]); end; procedure GetData; begin PeekNamedPipe(read_stdout, @buf, BufSize - 1, @bytes_read, @bytes_available, nil); //check to see if there is any data to read from stdout if (bytes_read <> 0) then begin ZeroBuffer; if (bytes_available > BufSize - 1) then while (bytes_read >= BufSize - 1) do begin ReadFile(read_stdout, buf, BufSize - 1, bytes_read, nil); //read the stdout pipe Output := Output + Buf; ZeroBuffer; end else begin ReadFile(read_stdout, buf, BufSize - 1, bytes_read, nil); Output := Output + Buf; end; end; end; begin Output := ''; Result := 255; // indicate some error if IsWindowsNT then //initialize security descriptor (Windows NT) begin InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@sd, true, nil, False); sa.lpSecurityDescriptor := @sd; end else sa.lpSecurityDescriptor := nil; sa.nLength := sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle := true; //allow inheritable handles (* if not(CreatePipe(newstdin,write_stdin,@sa,0)) //create stdin pipe then RaiseError('CreatePipe'); *) if not (CreatePipe(read_stdout, newstdout, @sa, 0)) then begin // CloseHandle(newstdin); // CloseHandle(write_stdin); RaiseError('CreatePipe'); end; GetStartupInfo(si); //set startupinfo for the spawned process { The dwFlags member tells CreateProcess how to make the process. STARTF_USESTDHANDLES validates the hStd* members. STARTF_USESHOWWINDOW validates the wShowWindow member. } si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; si.wShowWindow := SW_HIDE; si.hStdOutput := newstdout; si.hStdError := newstdout; //set the new handles for the child process // si.hStdInput:=newstdin; //spawn the child process if not (CreateProcess(nil, PChar(CommandLine), nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi)) then begin // CloseHandle(newstdin); CloseHandle(newstdout); CloseHandle(read_stdout); // CloseHandle(write_stdin); RaiseError('CreateProcess'); end; ZeroBuffer; while True do begin GetExitCodeProcess(pi.hProcess, Result); //while the process is running if (Result <> STILL_ACTIVE) then break; GetData; end; GetData; CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // CloseHandle(newstdin); //clean stuff up CloseHandle(newstdout); CloseHandle(read_stdout); // CloseHandle(write_stdin); end; |
Re: Ausgabe einer Befehlszeile in eine Datei umleiten
Au ja, danke, das ist nett. Ich werde das mal ausprobieren...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz