[ACCEPTED]-What is the different between API functions AllocConsole and AttachConsole(-1)?-console

Accepted answer
Score: 13

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 13 first case you get a whole new console window, in 12 the second case, you use an existing console 11 window.

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

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

Some code to play 1 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;
}
Score: 5

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

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

Try 10 running this code from both a command prompt 9 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 8 prompt, two message boxes containing a 1 are 7 displayed, meaning both calls succeeded. When 6 run from Start -> Run, the first box 5 contains 1 and the second contains 0, meaning 4 that only the first call succeeded. The 3 second one fails because explorer.exe (which 2 is the parent of a process launched from 1 Start -> Run) doesn't have a console.

Score: 4

On Windows 7, when you execute cmd.exe, CreateProcess will have 72 the CREATE_NEW_CONSOLE flag, which will allocate a new console 71 rather than being attached to the parent 70 console (which is default behaviour when 69 the PE header contains Subsystem = 3 i.e. IMAGE_SUBSYSTEM_WINDOWS_CUI indicating 68 that it is a console application). This 67 means that AllocConsole will be called before the .exe image 66 entry point in the current process address 65 space.

AllocConsole creates a new conhost.exe instance, which paints 64 the GUI window, handles the mouse and keyboard 63 events and maintains and writes to the the 62 input buffer and maintains and reads from 61 the screen buffer, and when there is a keyboard 60 event, it updates the input buffer. AllocConsole also 59 sets the stdin handle in the ParameterBlock in the cmd.exe process 58 PEB to the console input buffer and the 57 stdout and stderr to the the console pseudohandles, and 56 sets the ConsoleHandle in the ParameterBlockto the PID of theconhost.exe` instance 55 that it is attached to.

cmd.exe is a console application 54 written in C, like diskpart.exe or setx.exe, which displays 53 the command prompt to the screen buffer 52 (stdout of cmd.exe) and reads a command from the stdin of cmd.exe and 51 interprets the key press events to display 50 to stdout as well as determine what command to 49 call and what to display to stdout as a result 48 (which might be a file in the handle in 47 the PEB and not sent to conhost). A command itself has 46 an stdin of either nothing, the read side of 45 an anonymous pipe, a file or the con file.

cmd.exe calls 44 functions like WriteFile which will call WriteConsole (which 43 is an alias of WriteConsoleA) if it is writing to a standard 42 handle (otherwise it calls NtWriteFile). This will 41 initiate an ALPC call to conhost.exe PID in ParameterBlock->ConsoleHandle, passing 40 the console pseudohandle and the buffer 39 to write the result to (or the buffer to 38 read from).

When you execute cmd /c from inside 37 cmd.exe, it creates a child cmd.exe, but does not supply 36 CREATE_NEW_CONSOLE, which results in the child cmd.exe attaching 35 to the same visible console i.e. conhost.exe instance 34 and AttachConsole is called before the entry point. This 33 is not the case with a child created with 32 admin /c (admin version of cmd.exe) if done in a non-elevated 31 cmd.exe, which needs to have a new conhost.exe instance because 30 it has different privileges. Similarly, when 29 starting a program, start supplies CREATE_NEW_CONSOLE, which opens 28 a new conhost.exe for its child process, but call and specifying 27 the program filename + extension as a raw 26 command do not open another console window, but 25 attach to the parent. cmd /c diskpart creates a cmd.exe child 24 that attaches to the console that the parent 23 is attached to and then that child creates 22 its own child diskpart.exe, which attaches to the console 21 that the parent is attached to.

When you 20 execute a GUI application, it is not allocated 19 or attached to a console. If you use AllocConsole within 18 the application, it will create a new conhost.exe console 17 window (which can be hidden by the application, i.e. blender 16 has window > toggle system console, and it does this by getting a handle 15 to the conhost.exe console window and then using using 14 ShowWindow with SW_HIDE on it), but will not create a child 13 process, because it is the console window 12 of the current process, so now there will 11 be 2 windows. You can also instead attach 10 to a console (using AttachConsole) belonging to a process 9 of pid. AttachConsole(-1) attaches to the parent pid. This will 8 use the conhost that that process is attached to.

You 7 cannot AttachConsole if you are already attached to a 6 console without using FreeConsole and you can't AttachConsole to 5 connect to the parent's console if you create 4 the process with DETACHED_PROCESS. CREATE_NO_WINDOW has the same effect 3 as DETACHED_PROCESS in that it does not attach to or allocate 2 a console for the console application but 1 does allow it to attach to the parent console.

Score: 0

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

More Related questions