Yola
Yola

Reputation: 19023

Whats wrong with my code to attach and use console from another process?

I have server process, its allocate console and redirect output and input to that console. With ShellExecute this server process spawn some clients, these client know server ProcessID. So, i try AttachConsole with next class:

Console::Console(DWORD dwProcessId)
{
    if (dwProcessId) {
        AttachConsole(dwProcessId);
    }
    else
        AllocConsole();

    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = 500;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);

    int hConHandle;
    long lStdHandle;
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    FILE *fp = _fdopen( hConHandle, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );

    std::ios::sync_with_stdio();
}

Console::~Console()
{
    FreeConsole();
}

But it doesnt work, it even erase output to console from server process. Hmm.. May only one process can output to console. Is it possible to send output to console from many processes?

Upvotes: 1

Views: 1047

Answers (2)

Yola
Yola

Reputation: 19023

Can somebody say to me why next changes bring my code to work well:

Console::Console(DWORD dwProcessId)
{
    if (dwProcessId) {
        AttachConsole(dwProcessId);
        HANDLE consoleHandle = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        if (consoleHandle == INVALID_HANDLE_VALUE)
            throw 1;
        if (!SetStdHandle(STD_OUTPUT_HANDLE, consoleHandle)) 
            throw 2;
    }
    else {
        AllocConsole();
        CONSOLE_SCREEN_BUFFER_INFO coninfo;
        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
        coninfo.dwSize.Y = 500;
        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
    }


    int hConHandle;
    long lStdHandle;
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    FILE *fp = _fdopen( hConHandle, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );
    }

Now clients created with ShellExecute can write to server console.

Upvotes: 0

John
John

Reputation: 5635

You should open CONOUT$ using CreateFile. Attaching to a console does not change the starndard handles that your process has inherited.

Upvotes: 1

Related Questions