Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Ausgabe einer Befehlszeile in eine Datei umleiten (https://www.delphipraxis.net/40366-ausgabe-einer-befehlszeile-eine-datei-umleiten.html)

Wuchst 14. Feb 2005 20:49


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:
  rar.exe a archiv.rar *.* > log.txt
funktioniert manuell. Beim Aufruf

Delphi-Quellcode:
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);
wird zwar das Archiv erzeugt, die Log-Datei wird aber nicht geschrieben. Wo ist da das Problem?

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!

bigg 14. Feb 2005 20:55

Re: Ausgabe einer Befehlszeile in eine Datei umleiten
 
über die unrar-DLL:
http://www.dsdt.info/tutorials/rar/?page=1

Wuchst 14. Feb 2005 22:03

Re: Ausgabe einer Befehlszeile in eine Datei umleiten
 
Das kann aber nur entpacken, wenn ich das richtig sehe...

bigg 14. Feb 2005 22:49

Re: Ausgabe einer Befehlszeile in eine Datei umleiten
 
huch, das ent habe ich mir wohl irgendwie dazu gedichtet, sorry :oops:

jensw_2000 15. Feb 2005 01:45

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

4toms 15. Feb 2005 02:00

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.

Zottel 15. Feb 2005 08:47

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:
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;
vielleicht hilft dir das ja weiter....

Wuchst 15. Feb 2005 12:13

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 21:59 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz