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

use*_*690 3 python windows winapi stdout

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

我的问题是如何检测 Windows 句柄是否通向控制台或nul?有 WinAPI 函数吗?

Ery*_*Sun 5

对于访问字符_isatty设备的文件(即GetFileType返回FILE_TYPE_CHAR. 要特别检测控制台句柄,您可以调用GetConsoleMode. 对于非控制台句柄,此调用失败。要获取传递给此函数的底层 Windows 句柄,请调用msvcrt.get_osfhandle。例如:

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
Run Code Online (Sandbox Code Playgroud)