P
Peter Nimmo
Hi,
I am writting a windows application that I want to be able to act as if
it where a Console application in certain circumstances, such as error
logging.
Whilst I have nearly got it, it doesn't seem to write to the screen in
the way I would expect.
The output is:
C:\>Test.exe
C:\>Outputting Line 1
Outputting Line 2
Outputting Line 3
Outputting Line 4
Outputting Line 5
Outputting Line 6
Outputting Line 7
Outputting Line 8
Outputting Line 9
Outputting Line 10
Instead of:
C:\>Test.exe
Outputting Line 1
Outputting Line 2
Outputting Line 3
Outputting Line 4
Outputting Line 5
Outputting Line 6
Outputting Line 7
Outputting Line 8
Outputting Line 9
Outputting Line 10
C:\>
Code is as follows:
#include <Tlhelp32.h>
#include <cstdio>
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include <ios>
BOOL RedirectIOToConsole(DWORD dwParent)
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
BOOL bRet = AttachConsole(dwParent);
if (!bRet)
return bRet;
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
ios::sync_with_stdio();
return bRet;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0
);
wchar_t buffer[2000+1] = { '\0' };
DWORD dwCallingProcessID = 0UL;
if (hSnapshot != (HANDLE)-1)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(hSnapshot, &pe))
{
DWORD MyPID = GetCurrentProcessId();
do
{
if (pe.th32ProcessID == MyPID)
{
dwCallingProcessID = pe.th32ParentProcessID;
if (RedirectIOToConsole
(pe.th32ParentProcessID))
{
//cerr << "Failed";
for (int i = 0;i < 10;i++)
printf("Outputting Line %d\n",i+1);
}
else
{
MessageBox(NULL,L"Failed",L"Attaching
Console",MB_ICONERROR);
}
}
} while (Process32Next( hSnapshot, &pe ));
}
CloseHandle(hSnapshot);
}
return 0;//Other code snipped for brevity
}
I am writting a windows application that I want to be able to act as if
it where a Console application in certain circumstances, such as error
logging.
Whilst I have nearly got it, it doesn't seem to write to the screen in
the way I would expect.
The output is:
C:\>Test.exe
C:\>Outputting Line 1
Outputting Line 2
Outputting Line 3
Outputting Line 4
Outputting Line 5
Outputting Line 6
Outputting Line 7
Outputting Line 8
Outputting Line 9
Outputting Line 10
Instead of:
C:\>Test.exe
Outputting Line 1
Outputting Line 2
Outputting Line 3
Outputting Line 4
Outputting Line 5
Outputting Line 6
Outputting Line 7
Outputting Line 8
Outputting Line 9
Outputting Line 10
C:\>
Code is as follows:
#include <Tlhelp32.h>
#include <cstdio>
#include <io.h>
#include <fcntl.h>
#include <iostream>
#include <ios>
BOOL RedirectIOToConsole(DWORD dwParent)
{
int hConHandle;
long lStdHandle;
FILE *fp;
// allocate a console for this app
BOOL bRet = AttachConsole(dwParent);
if (!bRet)
return bRet;
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "r");
*stdin = *fp;
setvbuf(stdin, NULL, _IONBF, 0);
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen(hConHandle, "w");
*stderr = *fp;
setvbuf(stderr, NULL, _IONBF, 0);
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
ios::sync_with_stdio();
return bRet;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0
);
wchar_t buffer[2000+1] = { '\0' };
DWORD dwCallingProcessID = 0UL;
if (hSnapshot != (HANDLE)-1)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(hSnapshot, &pe))
{
DWORD MyPID = GetCurrentProcessId();
do
{
if (pe.th32ProcessID == MyPID)
{
dwCallingProcessID = pe.th32ParentProcessID;
if (RedirectIOToConsole
(pe.th32ParentProcessID))
{
//cerr << "Failed";
for (int i = 0;i < 10;i++)
printf("Outputting Line %d\n",i+1);
}
else
{
MessageBox(NULL,L"Failed",L"Attaching
Console",MB_ICONERROR);
}
}
} while (Process32Next( hSnapshot, &pe ));
}
CloseHandle(hSnapshot);
}
return 0;//Other code snipped for brevity
}