How to detect that stdio was redirected to nul?

Question:

I’m developing a package to fix several issues with Unicode in Python run in standard Windows console environment: https://github.com/Drekin/win-unicode-console. The key operation is to replace the standard stream objects when needed. For this I need to detect whether the standard streams were redirected or not. Python method isatty() works OK with one exception: If a stream was redirected to nul, then isatty() returns True.

My question is how to detect whether a Windows handle leads to a console or to nul? Is there a WinAPI function for that?

Asked By: user87690

||

Answers:

The C runtime’s _isatty function returns true for files that access character devices, i.e. files for which GetFileType returns FILE_TYPE_CHAR. To detect a console handle in particular you can call GetConsoleMode. This call fails for a non-console handle. To get the underlying Windows handle to pass to this function, call msvcrt.get_osfhandle. For example:

import ctypes
import msvcrt

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
ERROR_INVALID_HANDLE = 6

def is_console(file_descriptor):
    handle = msvcrt.get_osfhandle(file_descriptor)
    if kernel32.GetConsoleMode(handle, ctypes.byref(ctypes.c_uint())):
        return True
    last_error = ctypes.get_last_error()
    if last_error != ERROR_INVALID_HANDLE:
        raise ctypes.WinError(last_error)
    return False
Answered By: Eryk Sun
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.