The main goal is
if you start the program from the command line it is written to the terminal it was started from. Even when started from GUI (say, a Run dialog), the stdout can still be written to, but is discarded since there it is not redirected anywhere;
This problem troubled me almost one day.
After I googled it many times, read lots of posts.
and make the conclusion :
AFAIK there is no way to do this.
The reason:
In PE structure, there is an item "Subsystem" in "IMAGE_OPTIONAL_HEARDER".
Value "IMAGE_SUBSYSTEM_WINDOWS_CUI" Means Windows character-mode user interface (CUI) subsystem.
Value "IMAGE_SUBSYSTEM_WINDOWS_GUI" Means Windows graphical user interface (GUI) subsystem.
Look this two pages for details.
http://bbs.csdn.net/topics/360238669#post-371345748
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680339%28v=vs.85%29.aspx
So you can't change it after program started.
Maybe AttachConsole() can create a console, but WriteLn still doesn’t work.
And project1.exe>out.txt doesn’t work either.
You must use WriteConsole() instead. And this is not stdout! It only output to the console handle.
function WriteConsole(hConsoleOutput: THandle; const lpBuffer: Pointer; nNumberOfCharsToWrite: DWORD; var lpNumberOfCharsWritten: DWORD; lpReserved: Pointer): BOOL;external 'kernel32' name 'WriteConsoleA';
i think the best way is:
make the program in console mode.
And hide the console window if started from GUI.
code like this
...
var
H: THandle;
begin
H := FindWindowEx(0, 0, nil, PChar(Utf8ToAnsi(Application.Params[0])));
if H <> 0 then
SetWindowPos(H, HWND_TOPMOST, 0, 0, 0, 0, $80);
...
end.
Anyway, there will be a splash window. ╮(╯_╰)╭
(In my computer it's about 100ms, so normal people may can't notice)
If you have any other idea, please tell me.