Re: To be or not to be (a console app)
Thanks everyone. I eventually made it work quite simply by using a combination of the suggestions here. The app's Linux build uses the traditional main() entry point which does very little, apart from calling a function called app_main(). The Windows build uses the traditional WinMain() which builds some argc and argv info and then passes it to the same app_main() function. I just needed to add these blue lines to make it all work:-
Code:
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int ret = (-1);
// Some stuff here to create argc and argv info
BOOL bConsole; FILE *pStdOut = NULL, *pStdErr = NULL;
if ((bConsole = AttachConsole(ATTACH_PARENT_PROCESS)) != 0)
{
// This only gets reached if we started from a console
pStdOut = freopen( "CONOUT$", "w", stdout );
pStdErr = freopen( "CONOUT$", "w", stderr );
}
ret = app_main (argc, argv);
if (pStdOut)
fclose (pStdOut);
if (pStdErr)
fclose (pStdErr);
if (bConsole)
FreeConsole();
return ret;
}
Seems to be working a treat so far. When started from a console, the app sends its output to the console window and it also closes down if I close the console, which is quite neat. The only (very minor) niggle is that the app doesn't detach itself cleanly from the console if I close the GUI app but leave the console open. After the app closes I need to select the console window and type a carriage return before I see the DOS prompt again. That's only a minor problem though. Apart from that it works great. :thumb:
Re: To be or not to be (a console app)
Quote:
Originally Posted by John E
I need to select the console window and type a carriage return before I see the DOS prompt again. That's only a minor problem though. Apart from that it works great.
This is what ~cConsoleInitializer did
Code:
~cConsoleInitializer()
{
if( File )
{
INPUT_RECORD InputRecord;
InputRecord.EventType = KEY_EVENT;
InputRecord.Event.KeyEvent.bKeyDown = TRUE;
InputRecord.Event.KeyEvent.dwControlKeyState = 0;
InputRecord.Event.KeyEvent.uChar.UnicodeChar = VK_RETURN;
InputRecord.Event.KeyEvent.wRepeatCount = 1;
InputRecord.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
InputRecord.Event.KeyEvent.wVirtualScanCode = MapVirtualKey( VK_RETURN, 0 );
DWORD Written = 0;
WriteConsoleInput( GetStdHandle( STD_INPUT_HANDLE ), &InputRecord, 1, &Written );
fclose( File );
FreeConsole();
}
}
Re: To be or not to be (a console app)
Thanks Joeman, that extra code is what I needed. It does seem a bit strange the FreeConsole() doesn't do the job cleanly but no matter, adding those extra lines has fixed the problem. :thumb:
Re: To be or not to be (a console app)
You're welcome :).
Also my code made sure it didn't break the command:
EXENAME > echo.txt
To make sure your app doesn't break that command, you need to adapt IsAConsole at the least like:
Code:
HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if ((bConsole = AttachConsole(ATTACH_PARENT_PROCESS)) != 0 && IsAConsole(StdOut))
This way it will still redirect to a file instead of printing out to the console
Re: To be or not to be (a console app)
Thanks again. I made that amendment but when I initially tested the redirection feature, I was surprised to find that the file only contained text from stdout - but no text from stderr.
So I did a bit of googling and realised that to redirect both stdout and stderr, the old DOS syntax was:-
Code:
EXENAME > echo.txt 2<&1
(which does actually work, BTW).
Well, I never knew that..! It's amazing what you learn once you start delving into things.... :)