Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi DosProgramm zur Echtzeit auf Memo oder sonst. umleiten (https://www.delphipraxis.net/134827-dosprogramm-zur-echtzeit-auf-memo-oder-sonst-umleiten.html)

aramintaros 29. Mai 2009 22:51


DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Hallo DP'ler,
ich habe vor diesen Code zu benutzen, möchte aber den Schreib- und Lesevorgang im Ram haben.
Meine Frage- wie kriege ich das ganze ins Ram anstatt auf die Festplatte??
Nach einigen Tagen mit Auseinanderstezungen von CreateProzess und GetConsoleOutput ist dieser Coder übrig und ich bin erstmal am Ende.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
  Memo1.Clear;
  RunCaptured('C:\', 'E:\MediaInfo\MediaInfo.exe'+ ' --Inform=Audio;%Format%\r\n%Format_Profile%\r\n%BitRate_Mode/String%\r\n%BitRate/String%\r\n%SamplingRate/String%'+
  'e:\FILME\oktober.avi', '/K '+ Edit1.Text);
  if Memo1.Lines.Strings[0]= 'MPEG Audio' then
  if Memo1.Lines.Strings[1]= 'Layer 3' then
  if Memo1.Lines.Strings[2]= 'Constant' then
  if Memo1.Lines.Strings[3]= '128 Kbps' then
  if Memo1.Lines.Strings[4]= '48.0 KHz'then
  ShowMessage('OK');
end;

function TForm1.RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;
var
  start: TStartupInfo;
  procInfo: TProcessInformation;
  tmpName: string;
  tmp: Windows.THandle;
  tmpSec: TSecurityAttributes;
  res: TStringList;
  return: Cardinal;
begin
  Result:= False;
  try
    tmpName:= 'Test.txt';
    FillChar(tmpSec, SizeOf(tmpSec), #0);
    tmpSec.nLength:= SizeOf(tmpSec);
    tmpSec.bInheritHandle:= True;

   tmp:= Windows.CreateFile(PChar(tmpName),
           Generic_Write, File_Share_Write,
           @tmpSec, Create_Always, File_Attribute_Normal, 0);

    try
      FillChar(start, SizeOf(start), #0);
      start.cb         := SizeOf(start);
      start.hStdOutput := tmp;
      start.dwFlags    := StartF_UseStdHandles or StartF_UseShowWindow;
      start.wShowWindow := SW_HIDE;
      if CreateProcess(nil, PChar(_exeName + ' '+ ''), nil, nil, True,
                       0, nil, PChar(_dirName), start, procInfo) then
      begin
        SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
        WaitForSingleObject(procInfo.hProcess, Infinite);
        GetExitCodeProcess(procInfo.hProcess, return);
        Result:= (return= 0);
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
        Windows.CloseHandle(tmp);
        res:= TStringList.Create;
        try
          res.LoadFromFile(tmpName);
          Memo1.Lines.AddStrings(res);
        finally
          res.Free;
        end;
        Windows.DeleteFile(PChar(tmpName));
      end
      else
      begin
        Application.MessageBox(PChar(SysErrorMessage(GetLastError())),
          'RunCaptured Error', MB_OK);
      end;
    except
      Windows.CloseHandle(tmp);
      Windows.DeleteFile(PChar(tmpName));
      raise;
    end;
  finally
  end;
end;

end.
Wenn mir da geholfen werden könnte wäre das SUPER, aber bitte nicht mit Links, habe so viel ausprobiert und bekomme nur Fehler.
:twisted: Angefangen von Schreibfehlern mit Dll's und im Arbeitsspeicher, bis daß das Programm nicht gefunden werden konnte. :twisted:

Mit der Funktion "function GetConsoleOutput" gibt es an dieser Stelle immer Probleme.
Delphi-Quellcode:
  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
Nach ein par Änderungen wird zwar fehlerfrei compiliert, aber ich habe Probleme mit dem Speicherzugriff oder es scheint das Programm nicht zu geben, was natürlich Quatsch ist.


In meinem Übriggeblieben Code habe ich versucht mit einem MemoryStream an dieser Stelle einsteigen, aber ich mache etwas falsch, es klappt nicht, und (vermutlich) genau da brauche ich eure Unterstützung.
Vielleicht mache ich nen Denkfehler, dann schreibt mit welchen, bin nicht der Erfahrenste :lol:
Delphi-Quellcode:
    tmp:= Windows.CreateFile(PChar(tmpName),
           Generic_Write, File_Share_Write,
           @tmpSec, Create_Always, File_Attribute_Normal, 0);
Habe vor das ganze für die Mediainfo_Cli, Avidemux_CLI und FFMepg_CLI auszubauen.

quendolineDD 29. Mai 2009 22:55

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Also ich kenne das über Pipes. Das somit die Konsole simuliert werden kann. Gibt auch Beispiele dazu hier im Forum.

aramintaros 29. Mai 2009 23:02

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Ich habe schon einige ausprobiert und bekomme immer Fehler, was kann ich tun,, um diesen Code zu benutzen, er funzt fehlerfrei, ich habe stundenlang gelesen und probiert bevor ich diesen Thread geschrieben habe

RWarnecke 29. Mai 2009 23:06

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
:wiejetzt: Was ist denn nun, bekommst Du einen Fehler und wenn ja in welcher Zeile oder funktioniert er einwandfrei ? Suchst Du vielleicht soetwas.

Edit:
Ersetze mal Deine Variablen durch feste Werte.

Satty67 29. Mai 2009 23:15

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Glaube er will StdOut direkt in den Speicher
Delphi-Quellcode:
start.hStdOutput := tmp;
also dass tmp nicht mehr ein Datei-Handle, sondern ein MemoryStream.Handle ist (was nicht klappt, weil Stream <> File)

...glaube ich?

aramintaros 29. Mai 2009 23:20

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Habe natürlich schon die Variable gegen feste Werte getauchst, ohne das gewünschte Ergebnis, und auch der Link funzt nur nach umbauen mit Laufzeitfehlern.
Ab dieser Stelle gibt es bei allen ander funtions Probleme, ich habe keine ahnung warum.
Delphi-Quellcode:
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
Der Compiler schmeist Fehler raus mit Arbeitsspeicher, Dll und Programm nicht gefunden, trotz fester Werte.

aramintaros 29. Mai 2009 23:23

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Für Satty67,

das ist richtig, ich möchte daß "tmp" kein File mehr ist sondern im Ram behandelt wird.

RWarnecke 29. Mai 2009 23:28

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Ich habe mal im I-Net diesen Sourcecode gefunden, damit funktioniert es wunderbar:

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;

aramintaros 29. Mai 2009 23:34

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Wie genau wird diese Fuction über einen Buttonklich aufgerufen? bitte vertändlich, am besten mit dem Programm von "mediainfo.exe", vermutlich mache ich da nen Fehler, Sie läßt sich schon ohne Probs compilieren :bounce1:

jaenicke 29. Mai 2009 23:37

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Du erstellst jeweils eine TStringList für die Ausgaben und übergibst das zusammen mit dem Befehl an die Funktion.

Und eine Alternative, bei der du die Ausgabe bereits während das Konsolenprogramm noch läuft bekommst, wäre TDosCommand.

aramintaros 29. Mai 2009 23:41

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Zitat:

Zitat von jaenicke
Und eine Alternative, bei der du die Ausgabe bereits während das Konsolenprogramm noch läuft bekommst, wäre TDosCommand.

jaenicke, kannst du mir das genauer erklären? Werde um diese Uhrzeit nochmal richtig wach bei diesem Thema. :)

RWarnecke 29. Mai 2009 23:43

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Zitat:

Zitat von aramintaros
Wie genau wird diese Fuction über einen Buttonklich aufgerufen? bitte vertändlich, am besten mit dem Programm von "mediainfo.exe", vermutlich mache ich da nen Fehler, Sie läßt sich schon ohne Probs compilieren :bounce1:

So wie Sebastian es schon gesagt hat, Du erstellst zwei Stringlisten. Denn Wert für die Variable command setzt Du vorher in einer lokalen Variable zusammen. Dabei benutzt Du diese Funktion um die Systemvariablen aufzulösen. Damit sollte es dann klappen.

jaenicke 29. Mai 2009 23:45

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Zitat:

Zitat von aramintaros
jaenicke, kannst du mir das genauer erklären? Werde um diese Uhrzeit nochmal richtig wach bei diesem Thema. :)

Ich meine das:
http://maxxdelphisite.free.fr/doscmd.htm
Da bekommst du jede Zeile direkt, wenn das Konsolenprogramm sie ausgibt.

Mit der oben geposteten Lösung bekommst du sie ja erst, wenn das Konsolenprogramm beendet ist.

aramintaros 29. Mai 2009 23:51

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Ist denn das kompatible mit delphi 2009?

jaenicke 29. Mai 2009 23:55

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mit leichten Änderungen wegen Unicode ja. Im Anhang einmal eine entsprechend angepasste Version.

aramintaros 30. Mai 2009 00:01

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Hey hallo, diese Unit muss ja ertsmal eingebunden sein, bevor sie funzt, hier stoße ich an meine Grenzen, ich habe noch nie eine fremde Unit in meinen Progs benötigt, ist das kompliziert??

aramintaros 30. Mai 2009 00:02

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Habe im Eifer des Gefechtes nicht bemerkt, daß es auf ner anderen Seite weitergeht, sorry

RWarnecke 30. Mai 2009 00:06

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Die Unit über's Projekt hinzufügen und in der FormUnit in die Uses-Klausel einfügen. Dann kannste die Funktionen der eingebunden Unit verwenden.

jaenicke 30. Mai 2009 00:07

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Du öffnest das Package (.dpk) und klickst dann in der Projejtverwaltung mit rechts drauf und dann auf installieren. Dann ist die Komponente installiert. Jetzt kannst du die aufs Formular legen. Und dann mach einfach mal nen Memo und zwei Buttons dazu:
Delphi-Quellcode:
procedure TFormX.Button1Click(Sender: TObject);
begin
  DosCommand1.OutputLines := Memo1.Lines;
  DosCommand1.CommandLine := 'cmd';
  DosCommand1.Execute;
end;

procedure TFormX.Button2Click(Sender: TObject);
begin
  DosCommand1.SendLine('dir', True);
end;
Wenn du auf den ersten Knopf drückst, wird die Kommandozeile gestartet und du siehst direkt die Ausgabe im Memo. Und wenn du auf den zweiten Knopf drückst, wird an diese Kommandozeile der Befehl dir gesendet. Und auch dessen Ausgabe siehst du direkt.

aramintaros 30. Mai 2009 00:08

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Werde es sofort versuchen :lol:

aramintaros 30. Mai 2009 00:29

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Obwohl ich die Anweisung "DosCommand_2009" in die Uses geschrieben habe, bekomme ich Fehler. Was Habe ich da falsch gemacht?
Delphi-Quellcode:
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, DosCommand_2009;

type
und diese erst wenn ich den Butonklick fertig mache.
Delphi-Quellcode:
  DosCommand1.OutputLines := Memo1.Lines;
  DosCommand1.CommandLine := 'cmd';
  DosCommand1.Execute;

jaenicke 30. Mai 2009 00:30

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Wenn du es gemacht hättest wie ich es gesagt habe, würde Delphi das automatisch gemacht haben.

Aber ohne dass du die Fehler nennst, kann natürlich auch niemand etwas dazu sagen... :roll:

aramintaros 30. Mai 2009 00:43

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Habe den Fehler gefunden, ich habe nicht verstanden, daß es es sich um eine VCL-Komponente handelt, nachdem ich diese benutze sind auch die Fehler weg.

aramintaros 30. Mai 2009 00:50

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Ein hoch an denjenigen, der diese Unit geschrieben hat, sie funzt ganz klasse.
Euch möchte ich für eure Bemühungen und Geduld danken, habe gerade mit dem *.dpk oder Package etwas dazu gelernt.
Einen herzlichen Dank, eine arbeitsreiche Nacht, ein geruhsames Wochende und nen schönen Wochenanfang :lol:
Gruß aramintaros

OldGrumpy 30. Mai 2009 08:06

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Etwas grundlegendes noch, aramintaros, das Du Dir bitte schleunigst angewöhnst: Wenn Du schreibst "da gibt es einen Fehler", dann bitte auch dazuschreiben, welchen genau. Am bequemsten geht das, indem Du die entsprechende(n) Zeile(n) mit der Fehlermeldung vom Compiler einfach als Zitat in Dein Posting kopierst. Wenn Dein Auto nicht funktioniert, dann gehst Du schließlich auch nicht in die Werkstatt und sagst "Auto kaputt. Heilemachen!" sondern beschreibst das Problem möglichst genau. Oder? :mrgreen:

aramintaros 30. Mai 2009 09:02

Re: DosProgramm zur Echtzeit auf Memo oder sonst. umleiten
 
Ich werde in Zukunft auf eine genaue Fehler- und Compilermeldung achten. Danke für den Hinweis, das macht es sicherlich einfacher :thumb:


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