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 "In Konsole arbeiten" - Funktion tuts nicht immer (https://www.delphipraxis.net/39432-konsole-arbeiten-funktion-tuts-nicht-immer.html)

Mr_G 2. Feb 2005 16:40


"In Konsole arbeiten" - Funktion tuts nicht immer
 
Folgendes:
Ich habe eine Funktion (glaube ich habs sie von delphi-source.de) mit der man ein Proggi in der Konsole ausführen kann und den Konsolenoutput direkt zurückbekommt.
Delphi-Quellcode:
function GetConsoleOutput(const Command: String; var Output, 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
    Stream := TMemoryStream.Create;
    try
      while true do begin
        succeed := ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil);
        if not succeed then break;
        Stream.Write(Buffer, NumberOfBytesRead);
      end;
      Stream.Position := 0;
      Output.LoadFromStream(Stream);
    finally
      Stream.Free;
    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);
      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;
Ich benutze die Funktion um mittels Diruse (einem Proggi von Microsoft das die Größe von Ordnern bzw. Dateien ermittelt und noch vieles mehr kann...) eine bestimmte Ordnergröße herauszufinden.
Das Problem liegt meiner Meinung nach daran das der Prozess nicht erstellt werden kann. Ich habe diese Funktion dummerweise in einer älteren Version meines Proggis mal getestet und da hats funktioniert, da ich mich aber nicht mit Pipes und was man da alles braucht auskenne, bin mit meinem Latein nun am Ende...

Meine Frage: Woran kann das liegen?

P.S.: Ich habe natürlich auch funktionen gefunden mit denen man die Ordnergröße direkt auslesen kann, diese funktionieren aber nicht recht und sind zu langsam. Wenn mir jemand eine schnelle und genaue Möglichkeit die Größe eines Ordners auszulesen aufzeigt wäre ich auch dankbar!

Mr_G 3. Feb 2005 20:26

Re: "In Konsole arbeiten" - Funktion tuts nicht im
 
Hat denn keiner nen Ausweg parat? :cry: *push*

Mr_G 5. Feb 2005 22:15

Re: "In Konsole arbeiten" - Funktion tuts nicht im
 
*verlassen fühl* :cry: *push*

mirage228 5. Feb 2005 22:27

Re: "In Konsole arbeiten" - Funktion tuts nicht im
 
Hi,

ich verwende diese Funktion, um den Konsolenoutput zurückzubekommen:
Delphi-Quellcode:
// based on [url]http://www.swissdelphicenter.com/de/showcode.php?id=990[/url]
function RunCaptured(const DirName, ExeName, CmdLine: string;
  OutPut: TStrings; var ReturnCode: Cardinal): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  FileName: string;
  FileHandle: THandle;
  SecurityAttributes: TSecurityAttributes;
begin
  Result := False;
  try
    // set a temporary file
    FileName := 'Test.tmp';
    FillChar(SecurityAttributes, SizeOf(SecurityAttributes), #0);
    SecurityAttributes.nLength := SizeOf(SecurityAttributes);
    SecurityAttributes.bInheritHandle := True;
    FileHandle := Windows.CreateFile(PChar(FileName),
      GENERIC_WRITE, FILE_SHARE_WRITE, @SecurityAttributes, CREATE_ALWAYS,
      FILE_ATTRIBUTE_NORMAL, 0);
    try
      FillChar(StartupInfo, SizeOf(StartupInfo), #0);
      StartupInfo.cb         := SizeOf(StartupInfo);
      StartupInfo.hStdOutput := FileHandle;
      StartupInfo.dwFlags    := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
      StartupInfo.wShowWindow := SW_HIDE;
      // start the program
      if CreateProcess(nil, PChar(ExeName + ' ' + CmdLine), nil, nil, True,
        0, nil, PChar(DirName), StartupInfo, ProcInfo) then
      begin
        SetPriorityClass(ProcInfo.hProcess, IDLE_PRIORITY_CLASS);
        WaitForSingleObject(ProcInfo.hProcess, Infinite);
        GetExitCodeProcess(ProcInfo.hProcess, ReturnCode);
        // PHP.exe returns 255 on parse errors!
        Result := True;
        CloseHandle(ProcInfo.hThread);
        CloseHandle(ProcInfo.hProcess);
        Windows.CloseHandle(FileHandle);
        // Add the output
        if (OutPut <> nil) then
          OutPut.LoadFromFile(FileName);
      end;
      Windows.DeleteFile(PChar(FileName));
    except
      Windows.CloseHandle(FileHandle);
      Windows.DeleteFile(PChar(FileName));
      Result := False;
    end;
  finally
  end;
end;
Vielleichgt hilfts Dir ja ;)

mfG
mirage228


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:15 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 by Thomas Breitkreuz