如何检测到 stdio 被重定向到 nul?

How to detect that stdio was redirected to nul?

我正在开发一个包来解决标准 Windows 控制台环境中 Python 运行 中 Unicode 的几个问题:https://github.com/Drekin/win-unicode-console。关键操作是在需要时替换标准流对象。为此,我需要检测标准流是否被重定向。 Python 方法 isatty() 工作正常,但有一个例外:如果流被重定向到 nul,则 isatty() returns True.

我的问题是如何检测 Windows 句柄是指向控制台还是指向 nul?是否有用于此的 WinAPI 函数?

C 运行时的 _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。例如:

import ctypes
import msvcrt

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

def isconsole(fd):
    handle = msvcrt.get_osfhandle(fd)
    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