Reputation: 217
I have a Win32 application written in C that can have its console output via printf()
redirected to a log file.
It would be nice if I could have my app detect if it had been started with or without a redirect >
.
Any ideas?
Upvotes: 12
Views: 4079
Reputation: 217
Tom, thanks for the input.
I did some experiments and found this works for me..
fpos_t pos ;
fgetpos (stdout, & pos) ;
When an application's output is being redirected to a file, fgetpos()
sets pos
to zero. It makes sense since its freshly opened stderr for you.
EDIT: Actually, the value returned may be a positive integer if text has already been redirected to the log/file. So in your code you'd have something like if (pos >= 0) bfRedirected = TRUE;
When an application's output is not being redirected - it's going to the console device - not a file, so fgetpos()
will set pos
to -1.
Upvotes: 6
Reputation: 11
Example from https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/isatty?view=msvc-170
#include <stdio.h>
#include <io.h>
int main( void )
{
if( _isatty( _fileno( stdout ) ) )
printf( "stdout has not been redirected to a file\n" );
else
printf( "stdout has been redirected to a file\n");
}
Upvotes: 1
Reputation: 41805
The reliable way is to use GetFinalPathNameByHandle
to check the stdout file handle, if it's not redirected then an error will be returned
TCHAR chPath[MAX_PATH];
if (GetFinalPathNameByHandle(GetStdHandle(STD_OUTPUT_HANDLE), chPath, MAX_PATH, 0))
std::cout << "stdout redirected to " << chPath << '\n';
else
std::cout << "stdout not redirected" << '\n';
That API is available from Windows Vista onward. On older Windows GetMappedFileName
needs to be used like this
Upvotes: 2
Reputation: 4490
Method from Microsoft: WriteConsole fails if it is used with a standard handle that is redirected to a file. If an application processes multilingual output that can be redirected, determine whether the output handle is a console handle (one method is to call the GetConsoleMode function and check whether it succeeds).
Upvotes: 1
Reputation: 136201
I think that pipes are blind by nature, so you don't have a built-in way to tell whether you're being redirected. Moreover, trying to find out what's happening behind an abstraction layer is a bad habit.
If you really need to control your output, add the log file name as a command line parameter!
That being said, you can make some smart guesswork to find out:
Upvotes: 2
Reputation: 754753
AFAIK the answer to this is that you can't. Output redirection works by simply reading the stream of output from a given program and redirecting it to another pipe / stream. The design of file / streams is such that the writer is ignorant of the reader to the point that you shouldn't know you are being read.
Even detecting that there was a reader would be of no use because there is one in the normal case. The console is reading the output of your program and displaying it to the screen already.
Upvotes: 0