![]() |
Delphi-Version: XE
CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Hallo :)
Ich habe auch mal wieder ein Problem :lol: Ich habe in den letzten Stunden die frei verfügbare Unit ![]() versucht für objektorientieren Einsatz umzuschreiben, aber auch versucht den größten Teil der Unit zu übernehmen und die Struktur zu erhalten. Die Unit leitet Ein- und Ausgaben in/aus der Eingabeaufforderung (cmd.exe Prozess) in/aus Delphi um. Problem ist die Schleife (repeat-until) im Originalcode, die ich in der Konsole so nicht einsetzen kann/will. Also habe ich es in eine Klasse umgeschrieben:
Delphi-Quellcode:
Im Create erzeuge ich die Prozessinstanz (cmd.exe) und versorge sie dann in SendeZeile mit Eingabe und ließ in der selben Methode nach kurzem warten (hBufferWarteZeit=200ms) den Buffer aus und leite es über RC_LineOut an meine Konsole weiter.
Type
TSysCmd = Class Public Constructor Create(pCmdDatei, pErrorStr, pStartOrdner : String); Procedure SendeZeile(pZeile : String); Var RC_LineOut: procedure(s: string); hBufferWarteZeit : Integer; Destructor Free(); Private Function IstWinNT : BOOLEAN; Procedure TeileZeilen(pText : String); const bufsize=1024; // 1KByte Buffer Var buf: array [0..bufsize-1] of AnsiChar; // Musste ich ändern von Char sonst falsche Zeichen si: tSTARTUPINFO; sd: tSECURITYDESCRIPTOR; pi: tPROCESSINFORMATION; newstdin, newstdout, read_stdout, write_stdin: tHandle; bread, avail: dword; Const CRLF=#13#10; Var RC_SendBuf: string; RC_End: Boolean; RC_ExitCode: Cardinal; End; Eingebunden in ein VCL Programm funktioniert das ganze auch perfekt, wenn ich das Objekt aber in einer Konsole erstelle dann wird cmd.exe garnicht erst erzeugt, weiß jemand warum? Das Hauptprogramm ist
Delphi-Quellcode:
weil ich es über lokale ressourcen steuere.
//{$APPTYPE CONSOLE}
Hier noch der CreateProcess-Block:
Delphi-Quellcode:
Wäre echt nett wenn mir jemand das mal erklären könnte :)
GetStartupInfo(si);
si.dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE; si.hStdOutput:=newstdout; si.hStdError:=newstdout; si.hStdInput:=newstdin; if not CreateProcess(pchar(pCmdDatei), nil, nil, nil, true, CREATE_NEW_CONSOLE, nil, nil {pChar(lStartOrdner)}, si, pi) then begin pErrorStr := 'OnCreate(SysCmd) - Fehler bei der Erstellung des Prozess "' + pCmdDatei + '"'; CloseHandle(newstdin); CloseHandle(newstdout); CloseHandle(read_stdout); CloseHandle(write_stdin); exit; end; Gruß !N |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Frag ich mal allgemeiner: Woran kann es liegen, dass CreateProcess(...) bei einer Anwendung mit GUI den Prozess erstellt, in einer Konsolenanwendung aber der Prozess garnicht erst erstellt wird, oder nur kurz im Tastmanager aufblinkt und dann wieder verschwindet?
Vielleicht ist das wichtig: Ich hatte die Variablen
Delphi-Quellcode:
aus der Deklaration in der Methode RC_RUN genommen und sie global (private) im Kopf deklariert. Als ich auch
const bufsize=1024; // 1KByte Buffer
Var buf: array [0..bufsize-1] of AnsiChar; // Musste ich ändern von Char sonst falsche Zeichen si: tSTARTUPINFO; sd: tSECURITYDESCRIPTOR; pi: tPROCESSINFORMATION; newstdin, newstdout, read_stdout, write_stdin: tHandle; bread, avail: dword;
Delphi-Quellcode:
dort deklariert hatte, wurder in der GUI ebenfalls kein Prozess erzeugt, also habe ich
sa: tSECURITYATTRIBUTES
Delphi-Quellcode:
lokal in dem Construktor belassen. Nochmal: Wenn ich
Constructor TSysCmd.Create(pCmdDatei, pErrorStr, pStartOrdner : String);
Var sa: tSECURITYATTRIBUTES; // <<-- HIER //(...)
Delphi-Quellcode:
auch global deklariere, dann wird auch in der GUI kein Prozess erzeugt. Kann es also vielleicht an den Attributen liegen?
sa
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Wenn du in einem Konsolenprozess eine neuen Konsoleprozess startest, dann wird die Ausgabe in deinem Konzolenprozess gemacht, es sei denn du verwendest das CreateProcess Flag CREATE_NEW_CONSOLE .
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Ja, so stehts auch auf der Microsoft-Seite. Aber ich hab doch CREATE_NEW_CONSOLE genutzt?
Nebenbei: Gibt es auch einen Parameter, dass ein neuer Prozess erzeugt wird, wenn ich aus der Konsole (cmd.exe in einem Pfad) eine Konsolenanwendung ausführe [also irgendwas bei "C:\test.exe" zb.]
Delphi-Quellcode:
if not CreateProcess(pchar(pCmdDatei), nil, nil, nil, true,
CREATE_NEW_CONSOLE, nil, nil {pChar(lStartOrdner)}, si, pi) then begin |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Liste der Anhänge anzeigen (Anzahl: 1)
Würde es helfen, wenn ihr euch die Unit mal ansehen könntet und selber im Debugger laufen lassen könntet?
Hab sie mal angehangen. Einzubinden wie folgt:
Delphi-Quellcode:
Bitte schauts' euch mal an, Vielen Dank!
//(...) Zusatzinfos
Button1: TButton; Memo1: TMemo; dir: TEdit; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); //(...) procedure TForm1.Button2Click(Sender: TObject); begin syscmd.SendeZeile(dir.Text); end; procedure incoming(p: string); begin Form1.Memo1.Lines.Add(p); end; procedure TForm1.Button1Click(Sender: TObject); begin SysCmd := TSysCmd.Create('C:\Windows\System32\cmd.exe', Self.Caption, 'C:\'); syscmd.RC_LineOut := incoming; end; |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Nanu, das hab ich glatt übersehen.
Gibt denn CreateProcess einen Fehler zurück? |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Nein, leider nicht. Es scheint alles normal. Auch wenn ich Step-by-Step durch die Routine laufe, alles wie es sollte. Bis auf den fehlenden Prozess.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Klick die Konsolenanwendung mal doppelt im Explorer an und guck, was passiert.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Bleibt nur das Programm welches durch dein Programm gestartet wird nicht aktiv oder habe ich das falsch gelesen und dein Programm schließt sich ebenfalls?
Ich habe es so verstanden das du aus einem GUI-Programm ein Konsolenprogramm machst (aber ohne Konsolenausgabe?) welches andere Programme startet. Wie stellst du sicher das dein programm sich nicht beendet? Hast du eine Nachrichtenschleife in deinem Programm? |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Ich denke, er will mit CreateProcess ein Konsolenprogramm starten, nur beendet sich das Konsolenprogramm sofort wieder, weil es entweder so schnell fertig ist oder aber nötige Parameter fehlen und es sich deshalb sofort wieder beendet. Deswegen soll er das Programm mal über den Explorer starten. Beendet es sich da auch sofort wieder, ist alles in Ordnung mit seinem Code. Und dann am besten noch mal aus der Konsole starten, damit man eventuelle Fehlermeldungen sieht.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Im Hauptkonsolenprogramm habe ich ne Schleife, die auf die Eingaben wartet. Dieses Programm hat eine Instanz der Klasse TSysCmd. SysCmd soll über die zugewiesene Methode (
Delphi-Quellcode:
) seine Ausgaben diekt an den Besitzer liefern können. Das scheint mir auch nicht das Problem, das Ganze scheitert eher schon vorher beim erstellen des Prozesses.
syscmd.RC_LineOut := incoming
Ich habe mal ein Programm geschrieben, welches alle 2ms nach dem aktiven Prozess cmd.exe sucht. Nun ists klar, der Prozes wird erzeugt, aber beendet sich auch direkt wieder. Warum macht der denn sowas böses :P? @Luckie: Ich starte aus einer Delphi-Konsolenanwendung über CreateProcess den Prozess cmd.exe aus dem Systemverzeichnis (system32). Nur dass dieser sich, so wie oben beschrieben, direkt wieder beendet. |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Du sollst mir nicht erzählen, wie du es startest, sondern was passiert, wenn du es, wie ich es beschrieben haben startest. Die Informationen will ich haben.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Wenn ich C:\Windows\System32\cmd.exe öffne, dann kommt einfach nur die Eingabeaufforderung in der ausführenden directory, also "C:\Windows\System32\>".
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Das ist die Konsole. Und in der sollst du mal das Programm das Konsolenprogramm ausführen, was du mit CreateProcess starten willst.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Aber ich will mit CreateProcess doch nur die cmd.exe öffnen. Wenn ich in der cmd.exe, cmd.exe öffne bekomme ich 'ne Konsole in der Konsole (In der Eingabeaufforderung: C:\Windows\System32\>cmd.exe)
Ich glaube ich versteh nicht ganz, was du mir sagen willst, sorry :( |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Dann gib den Parameter /k mit, dann bleibt die Konsole offen, nacvh dem die Befehle abgearbeitet wurden.
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
/k hat leider nichts gebracht. Aber danke für deine Hilfe, bis hierhin.
Ich habe jetzt, nachdem ich eine GUI-Anwendung zum testen hatte und dort alles ging, eine Konsolenanwendung zum testen geschrieben. Komisch: Hier funktioniert alles wie gewünscht und erwartet. Ich werde mir mal meine Konsolenanwendung nochmal genau ansehen müssen. Vielen Dank aber für eure Hilfe! |
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Habe das ganze Problem beseitigt, indem ich das Create für die SysCmd in eine neue Prozedur verlegt habe. :roll:
|
AW: CreateProcess - Bei GUI geht's, bei Konsole tut sich nichts
Liste der Anhänge anzeigen (Anzahl: 1)
Man soll ja alte Threads ruhen lassen, aber ich hab auf die Schnelle mal ein Beispiel zusammengewürfelt, mit dem der standad I/O umgelenkt wird. Es mag nicht hübsch sein, aber es funktioniert :-)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:26 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 by Thomas Breitkreuz