views:

54

answers:

3

Hello. Is it possible to somehow change standart I/O functions handle on Windows? Language preffered is C++. If I understand it right, by selecting console project, compiler just pre-allocate console for you, and operates all standart I/O functions to work with its handle. So, what I want to do is to let one Console app actually write into another app Console buffer. I though that I could get first´s Console handle, than pass it to second app by a file (I don´t know much about interprocess comunication, and this seems easy) and than somehow use for example prinf with the first app handle. Can this be done? I know how to get console handle, but I have no idea how to redirect printf to that handle. Its just study-purpose project to more understand of OS work behind this. I am interested in how printf knows what Console it is assiciated with.

A: 

If you want to redirect printf to a handle (FILE*), just do

fprintf(handle, "...");

For example replicating printf with fprintf

fprintf(stdout, "...");

Or error reporting

fprintf(stderr, "FATAL: %s fails", "smurf");

This is also how you write to files. fprintf(file, "Blah.");

LukeN
Thanks. So, fprintf is redirectable printf? And, how does printf know which console is it´s default?
B.Gen.Jack.O.Neill
printf by default goes to whatever "stdout" is refering to, the standart output. Mostly the console, or if you redirect ("yourprogram >output.txt") the redirected file.
LukeN
+1  A: 

If I understand you correctly, it sounds like you want the Windows API function AttachConsole(pid), which attaches the current process to the console owned by the process whose PID is pid.

Jon Purdy
@Jon - I think you're right. http://msdn.microsoft.com/en-us/library/ms681952%28VS.85%29.aspx
dss539
A: 

If I understand you correct you can find the source code of application which you want to write in http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx. This example show how to write in stdin of another application and read it's stdout.

For general understanding. Compiler don't "pre-allocate console for you". Compiler use standard C/C++ libraries which write in the output. So if you use for example printf() the following code will be executed at the end will look like:

void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters
{
    DWORD n;
    UINT uCodePage = GetOEMCP();    // CP_OEMCP, CP_THREAD_ACP, CP_ACP
    PSTR pszText = _alloca (uTextLenght);

    // in the console are typically not used UNICODE, so
    if (WideCharToMultiByte (uCodePage,  0, pszwText, uTextLenght,
                             pszText, uTextLenght, NULL, NULL) != (int)uTextLenght)
        return;

    WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL);
    //_tprintf (TEXT("%.*ls"), uTextLenght, pszText);
    //_puttchar();
    //fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout);
    //_write (
}

So if one changes the value of STD_OUTPUT_HANDLE all output will be go to a file/pipe and so on. If instead of WriteFile the program use WriteConsole function such redirection will not works, but standard C/C++ library don't do this.

If you want redirect of stdout not from the child process but from the current process you can call SetStdHandle() directly (see http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx).

The "allocating of console" do a loader of operation system. It looks the word of binary EXE file (in the Subsystem part of IMAGE_OPTIONAL_HEADER see http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx) and if the EXE has 3 on this place (IMAGE_SUBSYSTEM_WINDOWS_CUI), than it use console of the parent process or create a new one. One can change a little this behavior in parameters of CreateProcess call (but only if you start child process in your code). This Subsystem flag of the EXE you define with respect of linker switch /subsystem (see http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx).

Oleg