Was ich eigentlich möchte ist:
- Bei Aufruf ohne -h soll die App ganz normal gestartet werden
- Bei Aufruf mit -h soll auf der Konsole (so die App von Konsole gestartet wurde) die Hilfe ausgegeben werden
Wurde die App mit -h nicht von Konsole gestartet, dann ist mir (erstmal) egal was geschieht...
Das Kernproblem besteht also darin: Wie bekomme ich unter Windows meinen Output in die Konsole, von der aus ich gestartet wurde?
Also in Win32\System.pp heisst es:
Code: Alles auswählen
procedure SysInitStdIO;
begin
{ Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be
displayed in a messagebox }
StdInputHandle:=longint(GetStdHandle(cardinal(STD_INPUT_HANDLE)));
StdOutputHandle:=longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
StdErrorHandle:=longint(GetStdHandle(cardinal(STD_ERROR_HANDLE)));
if not IsConsole then
begin
AssignError(stderr);
AssignError(stdout);
Assign(Output,'');
Assign(Input,'');
Assign(ErrOutput,'');
end
else
begin
OpenStdIO(Input,fmInput,StdInputHandle);
OpenStdIO(Output,fmOutput,StdOutputHandle);
OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
OpenStdIO(StdOut,fmOutput,StdOutputHandle);
OpenStdIO(StdErr,fmOutput,StdErrorHandle);
end;
end;
... aber ich finde keine MessageBox in der mein Writeln landet.
Mein Writeln bringt unter Windows eine Exception die ich mit try/except wegfangen kann.
Wenn ich ein Assign(Output,''); Rewrite(Output); davor schreibe kommt keine Exception, aber trotzdem auch keine Ausgabe auf der Konsole.
Mit vorherigem AllocConsole bekomme ich entlich eine Ausgabe:
Code: Alles auswählen
begin
{$I ConsoleHelp.lrs}
if ParamStr(1)='-h' then
begin
AllocConsole;
Assign(Output,'');
Rewrite(Output);
Writeln('Hallo');
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Allerdings macht mir Windows dann immer eine neue Konsole auf, auch wenn ich meine App von der Kommandozeile aus gestartet habe.
Ok, jetzt noch mal Tests ohne -WG, sodass meine App unter Windows als Konsolenanwendung gilt.
Damit funktioniert ja ein Writeln erstmal grundsätzlich und meine Formulare etc. werden trotzdem auch sichtbar.
Doof ist nur, dass dann beim Start meiner App (z.B. durch Klick auf das EXE im Explorer) per default immer eine Konsole aufgemacht wird.
Die bekomme ich zwar (für den Fall dass ich ohne -h aufgerufen wurde) mit FreeConsole() wieder weg, aber für kurze Zeit ist sie eben sichtbar. Unschön also.
Also -WG wieder eingeschaltet.
Lt.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx" onclick="window.open(this.href);return false; soll man mit AttachConsole(-1); die Konsole des Parent Prozesses bekommen.
Den Export
Code: Alles auswählen
AttachConsole(pid: LongInt): WINBOOL; external 'kernel32' name 'AttachConsole';
habe ich mir selbst gemacht, da er in rtl\inc\wininc\func.inc nicht enthalten war.
Bringt aber auch nichts, offenbar ist die Konsole von der aus ich meine App starte unter Windows nicht mein Parent?!
Statt dessen bekomme ich nach beenden meiner App einen Runtime error 217 in $0040A6DC in einer MessageBox (sowie 3 weitere Adressen) angezeigt.
Auch andere haben dafür scheinbar keine saubere Lösung gefunden (
http://stackoverflow.com/questions/5453 ... p-exe-help" onclick="window.open(this.href);return false;).
Der in
http://code.google.com/p/dualsubsystem" onclick="window.open(this.href);return false; beschriebene Trick mit 'nem Bla.com und Bla.exe gefällt mir jedenfalls nicht.
Nun denn, da werd' ich wohl für Windows doch ein TMemo verwenden müssen. Selbst Windows eigene Tools (wie z.B. WinDiff) machen das auf diese Weise.