Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi 'cmd-Befehl' in Delphi ausführen mit Ausgabe (https://www.delphipraxis.net/169697-cmd-befehl-delphi-ausfuehren-mit-ausgabe.html)

skunnes 5. Aug 2012 23:27

Delphi-Version: XE2

'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Hallo zusammen,

da ich noch recht neu bin wollte ich mal hier nachfragen, ob mir jemand helfen kann.

Es geht um folgendes:

Ich möchte doe Ausgabe eines cmd-Befehl, wie beispielsweise netstat -t in einem Memo-Feld anzeigen lasen.
Bevor ich diesen Post / Thread hier verfasst habe war ich natürlich selbst auf der Suche. Ich bin auch teils fündig geworden.
Die simple Ausgabe eines cmd-Befehls ist mir durch Shellexecute gelungen.

Ich benötige also eine Art executeandwaitforfinish Funktion. :)

Diese habe ich (zumindest denke ich das) auch gefunden.

Undzwar hier: http://www.delphipraxis.net/119316-a...e-fassung.html
und hier: http://www.delphi-treff.de/tipps/sys...ramm-anzeigen/

Da ich natürlich nicht den Thread von stz aufwecken wollte habe ich mich nun dazu entschlossen diesen hier zu erstellen.

Ich habe nämlich beide Funktionen eingefügt. Beim ausführen bekomme ich bei beiden jedoch folgende Fehlermeldung: http://d.pr/i/cgH8

Ich wäre sehr dankbar für jeglich Hilfe.

Sollten noch Fragen offen stehen oder weitere Informationen benötigt werden kann ich diese gerne liefern!

Gruß,
skunnes

alleinherrscher 6. Aug 2012 00:00

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Hi und willkommen im Forum.

Das liegt daran, dass neuere Delphi Versionen die Unicode Version von CreateProcess verwenden. In dieser Version ist der Parameter lpCommandLine veränderlich und nicht konstant. Siehe auch: http://embarcadero.newsgroups.archiv...104294937.html

Daher musst du folgenden Code verwenden:

Delphi-Quellcode:
function GetConsoleOutput(const Command : string;
                          Output, Errors : TStringList) : Boolean;
var
  Buffer           : array[0..255] of Char;
  CreationFlags    : DWORD;
  NumberOfBytesRead : DWORD;
  PipeErrorsRead   : THandle;
  PipeErrorsWrite  : THandle;
  PipeOutputRead   : THandle;
  PipeOutputWrite  : THandle;
  ProcessInfo      : TProcessInformation;
  SecurityAttr     : TSecurityAttributes;
  StartupInfo      : TStartupInfo;
  Stream           : TMemoryStream;
  sCmd             : string;
begin
  //Initialisierung ProcessInfo
  FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);

  //Initialisierung SecurityAttr
  FillChar(SecurityAttr, SizeOf(TSecurityAttributes), 0);
  SecurityAttr.nLength             := SizeOf(TSecurityAttributes);
  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(TStartupInfo);
  StartupInfo.hStdInput  := 0;
  StartupInfo.hStdOutput := PipeOutputWrite;
  StartupInfo.hStdError  := PipeErrorsWrite;
  StartupInfo.wShowWindow := SW_HIDE;
  StartupInfo.dwFlags    := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

  CreationFlags := CREATE_DEFAULT_ERROR_MODE or
                   CREATE_NEW_CONSOLE or
                   NORMAL_PRIORITY_CLASS;
  sCmd:=Command;
  UniqueString(sCmd);
  if CreateProcess(nil,
                   (PChar(sCmd)),
                   nil,
                   nil,
                   True,
                   CreationFlags,
                   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 ReadFile(PipeOutputRead, Buffer, 255, NumberOfBytesRead, nil) do
      begin
        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 ReadFile(PipeErrorsRead, Buffer, 255, NumberOfBytesRead, nil) do
      begin
        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;
Gruß, Michael

Medium 6. Aug 2012 00:26

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
[ot]Danke! Und zwar für eines der seltenen Male, wo ein "Frischling" eine Frage so traumhaft formuliert und recherchiert hat, sowie für eine präzise und direkte Antwort. *tränewegwisch* Mein Glaube in die Menschheit ist heute Nacht ein sichtbares Stück gewachsen :)
Und: Mehr als willkommen in der DP, skunnes! :dp:[/ot]

skunnes 6. Aug 2012 00:59

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Nabend und vielen Dank für die sehr schnelle Antwort und Lösung :)

Bummi 6. Aug 2012 01:06

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
ich möcht mich Medium unumwunden anschließen ...

haentschman 6. Aug 2012 06:04

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Ich mich auch... 8-)

Hinweis: Bei Bildern von Fehlermeldungen ist es besser sie hier direkt anzuhängen statt extern zu lagern. In meinem Falle kann ich z.B. auf deines nicht zugreifen (Scripts geblockt etc.). Desweiteren bleiben die Bilder erhalten sollte der externe Hoster mal Pleite gehen 8-)

MaBuSE 27. Mai 2019 11:53

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Zitat:

Zitat von haentschman (Beitrag 1177015)
Hinweis: Bei Bildern von Fehlermeldungen ist es besser sie hier direkt anzuhängen statt extern zu lagern. In meinem Falle kann ich z.B. auf deines nicht zugreifen (Scripts geblockt etc.). Desweiteren bleiben die Bilder erhalten sollte der externe Hoster mal Pleite gehen 8-)

Oder, wie hier geschehen, durch eine andere Bilddatei ersetzt ;)

Zitat:

Zitat von skunnes (Beitrag 1176997)
Beim ausführen bekomme ich bei beiden jedoch folgende Fehlermeldung: http://d.pr/i/cgH8

Ich habe sowieso nie verstanden, was an einem Screenshot besser sein soll als an dem PLAIN TEXT der Fehlermeldung.
Den Inhalt einer Fehlermeldung bzw. MessageDlg(...) kann man ja mit [Strg]+[C] auch kopieren.

Das Klappt sogar mit Titelzeile und Buttons:
Code:
---------------------------
Project1
---------------------------
'X' ist kein gültiger Integerwert.
---------------------------
OK  
---------------------------

Harry Stahl 27. Mai 2019 12:08

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Danke, für den Hinweis, war mir auch nicht bekannt...

Das wird mir in der Tat in Zukunft Arbeit abnehmen...

MaBuSE 27. Mai 2019 12:15

AW: 'cmd-Befehl' in Delphi ausführen mit Ausgabe
 
Zitat:

Zitat von Harry Stahl (Beitrag 1433195)
Danke, für den Hinweis, war mir auch nicht bekannt...
Das wird mir in der Tat in Zukunft Arbeit abnehmen...

;)

Das geht schon ewig. Ich glaube schon unter Win3.1

Und es geht nicht nur bei Delphi Anwendungen, sondern auch bei den Standard-Dialogen vieler anderen Anwendungen.
Ist eine Win32 API Funktionalität ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:31 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