Delphi-PRAXiS
Seite 1 von 3  1 23      

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:07 Uhr.
Seite 1 von 3  1 23      

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