Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decide an application to be of console/windows subsystem at run time

I have an MFC application that generates some reports and shows the same in the GUI. I have a requirement of running it as a console application, when passed with certain commandline argument. In the console mode it will generate the reports/errors in standard output/error and I should be able to redirect the same to any file.

For Ex. C:/temp MyApp.exe --console > report.txt should run my exe in console mode and redirect all the output to a text file. But if I run it without any console argument, it should be like a default MFC application.

To achieve my requirement, so far I have done is, changed the Linker > System > Subsytem from Windows to Console and added WinMainCRTStartup at Linker > Advanced > Entry Point

So now my app works fine when I run it with --console parameter from console/batch files. But when I run it directly, it still opens a cmd window (of course because it is now a console application). However, I am using FreeConsole() method to get rid of it but it still flashes for a brief second.

So I am just curious if there is a way to get rid of it completely, either by deciding the application's subsytem at run time or any other trick? Any suggestion will be appreciated.

like image 307
foobar Avatar asked Oct 23 '25 17:10

foobar


1 Answers

I'd suggest to keep your GUI application with the windows subsystem.

At the very beginning, when parsing command line, instead of creating the GUI windows (MFC inistialisation), you could create a console or attach with AttachConsole()

As a proof of concept, here how it could look like (for example in CxxxApp::InitInstance()):

...  // init code but before the the CMainFrame is created 

if(...) {   // suppose you want to go to the console
    if (! AttachConsole(ATTACH_PARENT_PROCESS))   // try to hijack existing console of command line
        AllocConsole();                           // or create your own.

    DWORD nw,nr;    // demo with windows native console i/o 
    char buff[32]; 
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), L"Who are you ? ", 14, &nw, NULL); 
    ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE), buff, sizeof(buff), &nr, NULL);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), "Hello ", 6, &nw, NULL);
    WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), buff, nr, &nw, NULL);
    ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE), buff, 1, &nr, NULL);
    ...
}

If you want to use C++ cin/cout, additional work is however needed. This other SO question addresses for example the redirecting of cout.

like image 98
Christophe Avatar answered Oct 26 '25 05:10

Christophe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!