![]() |
Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Hallo,
Ich habe in Dokus gelesen, das unter Linux eine Konsole unter /dev/ttyX ansprechbar ist. Gibt es da ein Äquivalent in Windows, falls ich auf der Kommandozeile die Konsole als Kommunikationsmedium ansprechen will/muss? Ist das "con"? Wie beim Kommando "copy con <myfile.txt>" Oder gibt es da für allgemeine Verwendung noch einen anderen Namen? |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Linux besitzt Standardkonsolen auf die man im Betrieb umschalten kann. Das gibt es bei Windows nicht, daher kann man nicht so einfach mit Konsolen kommunizieren.
|
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Willst du die Konsole zu einem/deinem Prozess ansprechen oder Irgendeine eines anderen Programms?
Es gibt ja nicht nur die eine Konsole, also gibt es da auch keine Allgemeine Adresse, um diese anzusprechen. Aber die Konsole, welche mit einem bestimmten Programm verbunden ist, läßt sich schon rausfinden und ansprechen (am Einfachsten natürlich die Konsole zum eigenem Programm) |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Zitat:
|
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo viakt133, du suchst dass!
lg. Astat |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Zitat:
[Fataler Fehler] Consts.pas(313): Ausgabedatei '..\..\dcu\Consts.dcu' kann nicht erstellt werden Habe deshalb gegoogelt und dabei die Windows-API Funktion CreateProcess gefunden. Die gibt doch den Handle des laufenden Prozesses zurück. Könnte dieser Handle nicht auch eine Schnittstelle zu jenem Prozess bilden, den ich von meinem Prozess aus ansprechen will? Werde mal sicherheitshalber auf ![]() Nun suche ich aber eine möglichst einfache Möglichkeit zur Prozesskommunikation ohne "Schnörkel". Nur zum Experimentieren. |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Zitat:
![]() Beispielcode gibt es z.B. in Free Pascal und MSEgui. Martin |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Zitat:
Habe bei meinem vorigen Thread die Attachment, durch nicht Componenten Version ersetzt. Du kannst es jetzt ohne Komponenten compillieren. lg. Astat |
Re: Name der Windoes Konsole zur KOmmunikation auf cmd.exe?
Hallo,
Danke erst mal für Eure Antworten. Daraus habe ich mir jetzt die folgende Lösung gebaut:
Delphi-Quellcode:
Nun wird aber in meiner Funktion immer wieder CreateProcess aufgerufen. Wie erreiche ich nun, das beim 2. bis n-ten Durchlauf immer wieder derselbe Prozess benutzt wird und nicht etwa neue Instanzen gestartet werden.
unit IPCConsole;
interface var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; SecurityAttr: TSecurityAttributes; PipeOutputRead: THandle; PipeOutputWrite: THandle; PipeErrorsRead: THandle; PipeErrorsWrite: THandle; ConsoleOutput : TStringList; ConsoleErrors : TStringList; function StartProcessDone(const AProcessStartCommand: String): Boolean; function SendCommandDone(const Command: String; var Output, Errors: TStringList): Boolean; implementation function StartProcessDone(const AProcessStartCommand: String): Boolean; var 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; function SendCommandDone(const Command: String; var Output, Errors: TStringList): Boolean; var Succeed: Boolean; Buffer: array [0..255] of Char; NumberOfBytesRead: DWORD; Stream: TMemoryStream; begin //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; ConsoleOutput.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; ConsoleErrors.LoadFromStream(Stream); finally Stream.Free; end; end; initialization ConsoleOutput := TStringList.Create; ConsoleErrors := TStringList.Create; finalization ConsoleErrors.Free; ConsoleOutput.Free; end. program p_console_read_write; uses SysUtils, Classes, IPCConsole in 'IPCConsole.pas'; var Command: String; procedure GetOutputFrom(var OutList: TStringList); var cnt,i: Integer; begin if Assigned(OutList) then begin i := 0; cnt := OutList.Count; while i<cnt do begin writeln('#### AUSGABE ####::: ',OutList[i]); inc(i); end; Writeln; Writeln; end; end; begin if StartProcessDone('MyProcess.exe') then repeat Write('Give a Command: '); Readln(Command); if SendCommandDone(Command, ConsoleOutput, ConsoleErrors) then GetOutputFrom(ConsoleOutput); until Command = 'q'; end. Im MSDN habe ich nur Named Pipes gefunden. Sollte das denn aber nicht auch mit unnamed Pipes gehen. Sviel ich bis jetzt davon verstanden habe, kann eine unnamed pipe nur in eriner Richtung (lesen oder schreiben) arbeiten. Hier im Quelltext werden aber schon zwei Pipes erzeugt, eine zum Lesen, eine zum Schreiben, wie ich es am Ende ja auch brauche. Aber wie greife ich nun auf diese Pipes zu? Während ich die Frage formuliere kommen mir Ideen, wie ich mein Ziel erreichen könnte. Aber dennoch habe ich folgende Fragen: Im obigen Quelltext werden zuerst, nach dem Füllen der StartupInfo die Pipes erzeugt. Dann wird in die Input-Pipe geschrieben, zB. mein Kommando. Das wird dann per MemoryStream in die Output Stringliste geschrieben. Aber wenn ich das jetzt starte, bleibt der Konsolenbildschirm schwarz. Warum komme ich nicht in die Repeat until Schleife? Wenn ich mir eine Routine schreibe, die per Pipe ein Kommando sendesn soll, hängt es am Screiben der Pipe. Werde wohl jetzt erst mal Interfaces weiter betrachten.
Delphi-Quellcode:
function SendCommand(const Command: String): Boolean;
var Buffer: array[0..255] of char; NumberOfBytesWritten: DWORD; begin if PipesUsed then begin Writeln('Schreiben des Kommandos -> ',Command); move(Command[1], Buffer, Length(Command)); Buffer[Length(Command)]:=#0; PipesUsed := WriteFile(PipeOutputWrite, Buffer, 255, NumberOfBytesWritten, nil); Result := PipesUsed; end else Result := PipesUsed; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:56 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-2025 by Thomas Breitkreuz