Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a Win32 console application detect if it has been run from the explorer or not?

Tags:

console

winapi

I have to create a console application which needs certain parameters. If they are missing or wrong I print out an error message.

Now the problem: If someone starts the program from the explorer by double-clicking the console window disappears immediately. (But the application is not entirely useless from the explorer, you could drag files onto it and it would work)

I could always wait for a keypress, but I don't want that if the user did start it from the command line.

Is there some way to distinguish between these situations?

like image 316
Daniel Rikowski Avatar asked Feb 04 '09 10:02

Daniel Rikowski


2 Answers

See http://support.microsoft.com/kb/99115, "INFO: Preventing the Console Window from Disappearing".

The idea is to use GetConsoleScreenBufferInfo to determine that the cursor has not moved from the initial 0,0 position.

Code sample from @tomlogic, based on the referenced Knowledge Base article:

// call in main() before printing to stdout // returns TRUE if program is in its own console (cursor at 0,0) or // FALSE if it was launched from an existing console. // See http://support.microsoft.com/kb/99115 #include <stdio.h> #include <windows.h> int separate_console( void) {     CONSOLE_SCREEN_BUFFER_INFO csbi;      if (!GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE), &csbi))     {         printf( "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());         return FALSE;     }      // if cursor position is (0,0) then we were launched in a separate console     return ((!csbi.dwCursorPosition.X) && (!csbi.dwCursorPosition.Y)); } 
like image 100
Per Mildner Avatar answered Oct 01 '22 05:10

Per Mildner


GetConsoleTitle()

I've seen code which performs

if (!GetConsoleTitle(NULL, 0) && GetLastError() == ERROR_SUCCESS) {     // Console } else {     // GUI } 

BUT... I've found that AttachConsole() is more helpful

In C++ (off the top of my head, and I'm no C++ programmer)

if (!AttachConsole(ATTACH_PARENT_PROCESS)) {     // GUI } else {     // Console, and you have a handle to the console that already exists. } 

Is more effective. Additionally, if you find yourself in a GUI environment and would like to stay there as long as you can, but later find something catastrophic has happened that could really use a dump to a console window (you can't be arsed writing an edit box window to lot it to or attach to the NT System log and throw up a MessageBox()) well then you can AllocConsole() later on in the process, when GUI methods have failed.

like image 41
bobsobol Avatar answered Oct 01 '22 04:10

bobsobol