views:

3009

answers:

3

Could you please explain me, what is the different between API functions AllocConsole and AttachConsole(-1) ? I mean if AttachConsole gets ATTACH_PARENT_PROCESS(DWORD)-1

Update: Sorry! My mistake. Of course AllocConsole instead of CreateConsole!

A: 

It has been a while since I used the winapi, but I looked up the MSDN documentation and I was not able to find the CreateConsole API function. So my guess is that CreateConsole is legacy stuff and has been replaced by AttachConsole. So there is probably no difference, but CreateConsole has probably been deprecated.

Matthias van der Vlies
+4  A: 

I don't think there's a function called CreateConsole, but there's AllocConsole.

Assuming that's what you meant, I think the difference is that AttachConsole(ATTACH_PARENT_PROCESS) can return ERROR_INVALID_HANDLE if the parent process doesn't have a console.

Try running this code from both a command prompt and Start -> Run:

#include <windows.h>
#pragma comment ( lib, "user32.lib" )

int main()
{
    BOOL b;
    char msg[1024];

    b = FreeConsole();
    sprintf(msg, "%d", b);
    MessageBox(NULL, msg, "FreeConsole", 0);

    b = AttachConsole(ATTACH_PARENT_PROCESS);
    sprintf(msg, "%d", b);
    MessageBox(NULL, msg, "AttachConsole", 0);

    return 0;
}

When run from a command prompt, two message boxes containing a 1 are displayed, meaning both calls succeeded. When run from Start -> Run, the first box contains 1 and the second contains 0, meaning that only the first call succeeded. The second one fails because explorer.exe (which is the parent of a process launched from Start -> Run) doesn't have a console.

Zach Hirsch
+6  A: 

Well, the fundamental difference is:

  • AllocConsole() will create a new console (and attach to it)
  • AttachConsole( ATTACH_PARENT_PROCESS /* -1 */) will not create a new console, it will attach to the existing console of the parent process.

In the first case you get a whole new console window, in the second case, you use an existing console window.

Of course, if you're already attached to a console (ie., you're a console mode program launched from cmd.exe) there's not much difference - you'll get an error with either API.

Also note that just because you detach from a console doesn't mean the detached console will be useful - for example, if you're a console process launched from a cmd window, that window essentially blocks until your process ends.

Some code to play with:

int main( int argc, char* argv[])
{
    int ch;
    BOOL bResult;

    printf( "default console\n");
    ch = getchar();

    bResult = FreeConsole();
    bResult = AllocConsole();    
    printf( "AllocConsole()\n");
    ch = getchar();

    bResult = FreeConsole();
    bResult = AttachConsole( ATTACH_PARENT_PROCESS);    
    printf( "AttachConsole( ATTACH_PARENT_PROCESS)\n");
    ch = getchar();

    return 0;
}
Michael Burr
Can this be used in C#.Net to create a console window for an executable compiled as a Windows Program (and not a Console Program)?
configurator
Yes it can. It is however far easier to get a console, just change the project's Output Type to Console Application.
Hans Passant
@configuratoir - as far as I know you can do this but I think you'll have to use p/invoke to call the Win32 APIs (not a big deal for these APIs) - I'm not sure if there's a framework equivalent.
Michael Burr
@nobugz - Yes, you can. See more at http://stackoverflow.com/questions/472282/show-console-in-windows-application#476894
abatishchev