如何检查 stdout 是否已在 Windows 上重定向到 NUL(在 Linux 上又称为 /dev/null)?

Meh*_*dad 5 c winapi stdout visual-c++

如何检查我的程序是否stdout已重定向到NUL
这样我就可以避免输出数据,因为它毫无意义。

我主要需要这个用于 Windows,但如果您有 Linux 解决方案,它可能会对将来的其他人有所帮助,所以也请随意发布。

Meh*_*dad 1

我自己想出来了。它很烦人。

#include <Windows.h>
#include <io.h>
#pragma comment(lib, "ntdll.lib")  // can instead use GetProcAddress (below)
extern "C" NTSTATUS __stdcall NtQueryVolumeInformationFile(
    HANDLE FileHandle, struct _IO_STATUS_BLOCK *IoStatusBlock,
    void *FsInformation, unsigned long Length,
    enum _FSINFOCLASS FsInformationClass);
bool isdevnull(FILE *file)
{
    struct FILE_FS_DEVICE_INFORMATION
    { unsigned long DeviceType, Characteristics; } fsinfo;
    struct { void *info, *status; } iosb;
    typedef NTSTATUS (__stdcall *PNTQIF)(
        HANDLE FileHandle, struct _IO_STATUS_BLOCK *IoStatusBlock,
        void *FsInformation, unsigned long Length,
        enum _FSINFOCLASS FsInformationClass);
    PNTQIF const ntqif =
        true  // True if you have ntdll.lib, false otherwise
        ? NtQueryVolumeInformationFile
        : (PNTQIF) GetProcAddress(
            GetModuleHandle(TEXT("ntdll.dll")),
            "NtQueryVolumeInformationFile");
    return ntqif(
        (HANDLE) _get_osfhandle(_fileno(stdout)),
        (struct _IO_STATUS_BLOCK *)&iosb,
        &fsinfo, sizeof(fsinfo),
        (enum _FSINFOCLASS)4
    ) == 0 && fsinfo.DeviceType == 0x00000015 /*FILE_DEVICE_NULL*/;
}
int main()
{
    bool b = isdevnull(stdout);
}
Run Code Online (Sandbox Code Playgroud)