Tuesday, January 13, 2009

Create console for nonconsole application.

First we need to create a console:
BOOL result=AllocConsole();
assert(result);
Then we need to get the handle to the console, and associate the console to the standard output stream:
HANDLE hOutput=CreateFile(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
SetStdHandle(STD_OUTPUT_HANDLE,hOutput);
In CRT, we also need make the stdout usable:
#include
#include
int hCrt=_open_osfhandle((intptr_t)hOutput,_O_TEXT);
FILE* hf=_fdopen(hCrt,"w");
*stdout=*hf
If in C++/CLI, We also need to replace System::Console::Out:
ref class __ConsoleWriter : public TextWriter
{
private:
HANDLE handle;
__ConsoleWriter(HANDLE handle):handle(handle){}
public:
virtual property System::Text::Encoding^ Encoding
{
System::Text::Encoding^ get()override
{
return System::Text::Encoding::UTF8;
}
}
virtual void Write(array^ buffer, int index, int count)override
{
array^ bytes=Encoding->GetBytes(buffer, index, count);
pin_ptr p=&bytes[0];
DWORD n;
WriteFile(handle, (LPVOID)p, bytes->Length, &n, NULL);
}
};
//Redirect the CLR output
Console::SetOut(gcnew __ConsoleWriter(hOutput));

That's it, quite simple.