![]() |
Handle von Konsolen-App?
Hi all,
gibts ne Möglichkeit sowas wie
Delphi-Quellcode:
auch für eine Konsolenanwendung zu machen?
hWindow := FindWindow('notepad', nil);
SetForegroundWindow(hWindow); Hat die überhaupt ein "Window" ? Danke Charly |
AW: Handle von Konsolen-App?
Diese Anwendung selber hat natürlich kein Window-Handle.
Deine Anwendung läuft in einem ConsoleHost und an ihm kann ein Terminal hängen. Wenn Sie aber in einer Console-/Terminal-Anwendung läuft angezeigt wird ... diese "Anwendung" hat natürlich ein Handle. z.B. cmd.exe > ConsoleWindowClass Windows-Terminal > CASCADIA_HOSTING_WINDOW_CLASS / Windows.UI.Core.CoreWindow / Windows.UI.Composition.DesktopWindowContentBridge / ... ![]() |
AW: Handle von Konsolen-App?
Guten Morgen Charly,
was möchtest Du denn machen? Mit einer Konsolenanwendung kann man ja klassischerweise nur per stdin / stdout kommunizieren, also im Prinzip nach stdin Tasteneingaben hinschicken und die Ausgabe aus stdout (oder stderr) auslesen. Wenn Du den Prozess selber steuerst / startest kannst Du Dich freilich an die streams dran hängen und beliebiges reinschreiben und auslesen. Eine Konsolenanwendung muss aber nicht unbedingt ein Terminal haben. Sie kann z.B. als child-prozess eines anderen Programmes komplett unsichtbar laufen gelassen werden. Da wüsste ich aber ehrlich gesagt keinen Weg, wie man an stdout / stdin eines schon laufenden Prozesses käme. |
AW: Handle von Konsolen-App?
ich habe folgenden Code in einer KonsolenApp
Delphi-Quellcode:
Und diese Kommandos "0,1,2,3,..." möchte ich von einem anderen Programm (einem Rest-Server) aus zur Konsolenanwendung schicken.
selcmd:= 3;
repeat case selcmd of 1 : tuewas; 2 : tue was anderes 3 : ..... else writeln('wrong command'); end; writeln; writeln; writeln('Commands'); writeln('0 : Quit the Kernel'); writeln('1 : Reset '); writeln('2 : Calc'); writeln('Enter command:'); readln(selcmd); until (selcmd=0); Die KonsolenApp läuft in einem "CMD-Fenster"??? z.B. nach einem Start mittels Konsolenanwendung.exe doppelklick bis sie "0" bekommt. Charly |
AW: Handle von Konsolen-App?
Die Löstung ist hier "notmalerweise" immer, dass man die Consolenanwendung startet und ihr ein anderes STDIN mitgibt, also einen Stream (Pipe), über Welchen man was dort rein gibt.
Und will man auf Ausgaben reagieren, dann auch noch STDOUT/STDERR auf eine Pipe umleiten, welche man dann ausliest. Wie z.B. das | (Piepe) bzw. > und < in der CMD. ![]() Klar, eventuell kann man auch das Fenster suchen und Tastendrücke simulieren, aber der Spaß beginnt schon damit, dass es viele Terminal-Programme gibt (nicht mehr nur die CMD.exe) und Jeder anders reagiert. z.B. das neue Windows Terminal verarbeitet Tastatur/Maus über DirectX. (wenn ich mich nicht irre) Aber sowas macht man nicht, da es zu unsicher ist. Wenn beide Seiten von dir kommen, dann wäre es kein Problem einen anderen Weg zu gehen, also z.B. eine "globale" NamedPipe auf die dein zusätzlich Programm lauscht und an Welche das andere Programm etwas sendet. Oder ein unsichtbares MessageOnly-Fenster generieren (so ähnlich wie das Application im Delphi), irgendwie dessen Handle rausgeben oder abrufen oder ihm einen bekannten Namen zu geben und dann via SendMessage etwas empfangen (WM_SETTEXT, WM_COPY oder sonstwas). Oder ansonsten jegliche andere IPC-Lösung, inkl. DDE, ActiveX und Sonstwas. |
AW: Handle von Konsolen-App?
Oh Je Oh Je
Zitat:
Ich kenne "prog1 | prog2" oder die Variante ne datei als Input "prog1 < file" oder so ähnlich auf der CMD Ebene. Aber wie muss ich die Zeile verstehen. Ist das Code in meiner KonsolenApp?? Zitat:
Wäre toll, da ich auch damit bisher nichts am Hut hatte Danke Charly |
AW: Handle von Konsolen-App?
![]() ![]() ![]() ![]() ![]() ![]() Aus den ersten Suchergebnissen... ![]() ![]() Zeigt zumindestens schonmal ansatzweise, wie das aussieht * Pipes erstellen * * mindestens hStdInput, wo du deine Befehle rein schreiben kannst * * und eventuell auch noch hStdOutput, wo die Antwort zurück kommt * dann damit den Prozess starten * auf dessen Ende warten * und währenddessen die Ein-/Ausgaben behandeln, also in StdIn reinschreiben und aus StdOut lesen (ja, andersrum, da aus Sicht des gestarteten Programms) Sonst hab ich jetzt nichts Fertiges anzubieten, aber z.B. bezüglich ![]() ![]() ![]() ![]() |
AW: Handle von Konsolen-App?
Was Du haben willst, ist ein klassisches CGI-Programm.
Mein olles Delphi7 bietet das unter Datei Neu weitere Web-Server-Anwendung und dort dann CGI-Einzelanwendung an. Damit hast Du schonmal alles, was eine entsprechende Konsolenanwendung benötigt. Die weitere Programmierung ist identisch mit der einer ISAPI.dll. Und die war ja hier ![]() Bei Delphi 7 ist dashier ein Grundgerüst für ein CGI-Programm:
Delphi-Quellcode:
und dashier eine ISAPI.dll:
program Project1;
{$APPTYPE CONSOLE} uses WebBroker, CGIApp, Unit1 in 'Unit1.pas' {WebModule1: TWebModule}; {$R *.res} begin Application.Initialize; Application.CreateForm(TWebModule1, WebModule1); Application.Run; end.
Delphi-Quellcode:
Und wenn man das TWebModule1 in beides einbindet, kann man sehr einfach aus einem Webmodul sowohl eine ISAPI.dll als auch ein CGI-Programm machen und umgekehrt (derweil: Sie sind absolut kompatibel).
library Project2;
uses ActiveX, ComObj, WebBroker, ISAPIThreadPool, ISAPIApp, Unit1 in 'Unit1.pas' {WebModule1: TWebModule}; {$R *.res} exports GetExtensionVersion, HttpExtensionProc, TerminateExtension; begin CoInitFlags := COINIT_MULTITHREADED; Application.Initialize; Application.CreateForm(TWebModule1, WebModule1); Application.Run; end. Achso: Man kann ein Konsolenprogramm auch per Pipe "bedienen", muss man bei CGI-Programmen aber nicht, das bekommt man hier geschenkt. (Zumindest war es bei Delphi 7 so, ob's aktuell auch noch so ist, müsstest Du mal überprüfen, kann mir aber nicht vorstellen, dass es hier jetzt auf einmal große Unterschiede geben könnte.) |
AW: Handle von Konsolen-App?
Das ist ja ein ganzer Sack an Info.
Da muss ich mich jetzt erst mal reinfinden Aber VIELEN Dank an alle Charly |
AW: Handle von Konsolen-App?
Zitat:
danke, das hat schon richtig geholfen. Kann jetzt meine KonsolenApp starten. Habe dann im Code von little_budda an der Stelle //jetzt mit ReadFile/WriteFile kommunizieren folgendes eingeführt:
Delphi-Quellcode:
Und jetzt was zum Verständnis.var chBuf : Array[1..2] of Char; written : longWord; begin ......... //jetzt mit ReadFile/WriteFile kommunizieren while true do begin chbuf[1]:= '3'; chbuf[2]:= #13; bSuccess:= WriteFile(WriteInput{g_hChildStd_IN_Wr}, chBuf, 2{dwRead}, Written{&dwWritten}, nil); if (NOT bSuccess) then begin err:= GetLastError; break; end; end; Wenn ich in der STARTUPINFO Struktur einen "Input-Handle" für die KonsolenApp erzeuge
Delphi-Quellcode:
sollte ich mit WriteFile doch direkt da reinschreiben könen? Oder nicht?
CreatePipe(StartStruct.hStdInput, WriteInput, @SecAttr, 0); //die Handles erzeugen
Oder muss ich in der KonsolenApp auch noch explizit aus dem neuen Handle lesen? Ich dachte eigentlich, das beim Starten der KonsolenApp deren StdInput schon umgebogen wird????? Ihr seht, mir fehlt da ganz Grundsätzliches Danke für weitere Hilfe Charly |
AW: Handle von Konsolen-App?
Das STARTUPINFO gibt der Anwendung ein optionales Handle. (ist das leer, dann werden die Standrad-Handles des Systems verwendet)
Du schreibst in
Delphi-Quellcode:
und in der anderen Anwendung kommt es dann bei GetStdHandle(STD_INPUT_HANDLE) an, bzw. bei den Delphi-APIs, welche das nutzen, wie z.B. ReadLn (ohne den File-Parameter).
WriteFile(PipeWrite, ...
Andersum genauso, wenn die andere Anwendung auf STD_OUTPUT_HANDLE schreibt, bzw. mit WriteLn, dann kommt es bei dir im PipeRead (STARTUPINFO.hStdOutput) |
AW: Handle von Konsolen-App?
Das heist also, daß ich in meiner Konsolenapp _nichts_ tun muß?
Das readln liest ja bereits aus StandardIn. Bei mir kommt in der KonsolenApp nämlich nichts an wenn ich z.B 2 Chars ('3' und #13) schicke. ABer in der Variablen "written" steht ne 2 und bSucess ist auch True. Und eigentlich sollte doch dann meine App die '3' mit nem CR dahinter genau wie ein Kommando wie von der Tastatur hier ne 3 und Enter behandeln? Das tut sie nicht!!!! Charly |
AW: Handle von Konsolen-App?
Wie schickst du diese Chars?
das Encoding ist schon wichtig. |
AW: Handle von Konsolen-App?
ReadLn ließt bis zum nächsten Zeilenumbruch und der ist unter Windows #13#10. Es gibt dazu auch die Konstante sLineBreak, mit der ist man dann plattformunabhängig, da sie automatisch den für die Zielplattform richtigen Wert enthält.
|
AW: Handle von Konsolen-App?
ReadLn ist es egal, es kommt allen Kombinationen zurecht, also CR, CR+LF oder LF (so wie die TStringList)
|
AW: Handle von Konsolen-App?
Hallo himitsu, Delphi.Narium
erstmal VIELEN Dank für eure Hilfe, ich habe da wirklich nur im Nebel gestochert. Jetzt gehts. Aber ihr habt beide nur teilweise recht. Meine Konsole/werauch ímmer kann wohl nur AnsiChar und somit sende ich:
Delphi-Quellcode:
// chBuf : Array[1..3] of AnsiChar = ('3',#13,#10); //geht
// chBuf : Array[1..3] of AnsiChar = ('3',#10); //geht chBuf : Array[1..2] of byte = (51,10); //geht begin bSuccess:= WriteFile(WriteInput{g_hChildStd_IN_Wr}, chBuf, 2 | 3 (je nach definition oben), Written, nil); Zitat:
Zitat:
Aber sLineBreak geht wiederum nicht, da es WideString ist. Danke Charly |
AW: Handle von Konsolen-App?
Ja, Delphi-Consolen können nur ANSI, bzw. OEM. (was sich jeweils umschalten ließe)
Aber wenn man nicht die uralten Delphi-Funktionen verwendet, dann wäre auch alles Andere Möglich.
Delphi-Quellcode:
function _WriteWString(var t: TTextRec; const s: WideString; width: Longint): Pointer;
var i: Integer; begin i := Length(s); _WriteSpaces(t, width - i); Result := _WriteLString(t, AnsiString(s), 0); end; procedure _ReadUString(var t: TTextRec; var s: UnicodeString); var Temp: AnsiString; begin // !!! FIXME _ReadLString(t, Temp, DefaultSystemCodePage); s := UnicodeString(Temp); end; Das sLineBreak hat per se in seiner Deklaration keinen Typen. Es müsste sich demnach jeweils an den Zieltyp anpassen (der Compiler dürfte es bereits gecastet übergeben). Und selbst wenn nicht, dann würde es bei Verwendung einfach implizit gecastet. Zitat:
Delphi-Quellcode:
procedure _ReadLn(var t: TTextRec);
{$IF not defined(CPU386)} var c: Word; begin while True do begin c := _ReadCharEx(t); if (c and $00ff) = cLF then break; // accept LF as end of line if (c and $ff00) shr 8 = cEOF then break; >>> if (c and $00ff) = cCR then begin c := _ReadCharEx(t); >>>>> if (c and $00ff) = cLF then break; // accept CR+LF as end of line if (c and $ff00) shr 8 = cEOF then break; // accept CR+EOF as end of line Dec(t.BufPos); // else CR+ anything else is not a line break. end; end; end; |
AW: Handle von Konsolen-App?
Liste der Anhänge anzeigen (Anzahl: 1)
ok, da ist ja wieder viel Stoff zu verdauen.
Möchte aber vorher ein weiteres evtl. neues? Problem zur Diskusion stellen. Ich habe ja eine Version, die meine ConsolenApp creiert und was hin schickt. Jetzt ist aber der Effekt so, daß wenn ich mein CreateProcess() in einem Formular habe, dann müssen die Parameter alle Wide-String-Variante sein, sonst mault der Compiler. Wenn ich das ganze Create/WriteFile in eine Unit auslagere, dann muss es Ansi-String sein. Ich habe die Projekte "CreateProcess" und "WebKernel" in eine Gruppe CreateProcessGroup gepackt und alles zusammengezipt. Ich häng dieses zip mit an. Vieleicht kann mir das ja jemand erklären. Danke Charly |
AW: Handle von Konsolen-App?
Zitat:
was mach ich mit _ReadUString? Wie kann ich das in meiner Konsole nutzen? Vieleicht kannst du ja mal mein Projekt anschauen. :-) Sorry für die viele Fragerei und Danke Charly |
AW: Handle von Konsolen-App?
Hi
Zitat:
Wie bzw. wo kann man das umschalten? In meinem Programm oder in den Eigenschaften der Konsole/CMD oder wer auch immer mit meiner KonsolenApp hochkommt? Charly :-( |
AW: Handle von Konsolen-App?
Die "alten" Pascal-Funktionen für den Dateizugriff sind Compiler-Magic.
Du machst damit nichts. z.B. ein
Delphi-Quellcode:
macht der Compiler intern zu einer Reihe von _WriteLString('abc'), _Write0Long('123), _Write0Ext(0.75), _Write0Bool(True) und _WriteLn()
WriteLn('abc', 123, 0.75, True);
Zitat:
![]() bzw. ![]() Und wenn man im Programm selber ANSI-File-APIs benutzt, wie z.B. CreateFileA, dann ![]() |
AW: Handle von Konsolen-App?
hi himitsu
gehört hier nicht hin, aber ich kann dir keine private Nachricht schicken. Zitat:
|
AW: Handle von Konsolen-App?
Hi
hier ![]() habe ich ne ganz tolle Beschreibung der Zusammenhänge gefunden. Charly |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:45 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