【问题标题】:How do I detect when output is being redirected?如何检测输出何时被重定向?
【发布时间】:2011-01-06 11:07:40
【问题描述】:

我有一个用 C 编写的 Win32 应用程序,它可以通过 printf() 将其控制台输出重定向到日志文件。

如果我能拥有我的应用程序那就太好了。检测它是否已在有或没有重定向'>'的情况下启动。

有什么想法吗?

【问题讨论】:

  • AFAIK,这是不可能的。所以我会阅读这篇文章,看看我是否错了......
  • 无从得知。我见过允许命令行选项执行不同功能的程序,这些功能通常仅在重定向输出时才打开。
  • 在 Windows 中不是 100% 确定,但在 Linux 中,有许多程序在是否使用管道时表现不同......最常见的例子是“ls”。
  • 感谢 fortran,我忘了说明我正在为 Windows 编码。

标签: winapi redirect console-application


【解决方案1】:

来自 Microsoft 的方法:WriteConsole 如果与重定向到文件的标准句柄一起使用,则会失败。如果应用程序处理的多语言输出可以重定向,判断输出句柄是否为控制台句柄(一种方法是调用GetConsoleMode函数,判断是否成功)。

【讨论】:

    【解决方案2】:

    可能有一种方法可以做到这一点 - 一个快速的谷歌产生了这个hit,它可能会给你一个正确方向的提示。

    【讨论】:

    • @Adam:实际上,这让我感到惊讶,所以不,我没有尝试过。我也觉得不可能! :)
    • 仅供参考,指向 codegear 的链接已失效,并且它也不会出现在 Wayback 机器中。
    【解决方案3】:

    汤姆,感谢您的意见。

    我做了一些实验,发现这对我有用..

    fpost_t pos ;
    
    fgetpos (stdout, & pos) ;
    

    当应用程序的输出被重定向到文件时,fgetpos() 将 'pos' 设置为零。这是有道理的,因为它为您新打开了 stderr。 编辑: 实际上,如果文本已经被重定向到日志/文件,则返回的值可能是一个正整数。所以在你的代码中你会有类似“if (pos >= 0) bfRedirected = TRUE;”的东西

    当应用程序的输出没有被重定向时 - 它会发送到控制台设备 - 而不是文件,因此 fgetpos() 会将 'pos' 设置为 -1。

    【讨论】:

      【解决方案4】:

      我认为管道本质上是盲目的,因此您没有内置方法来判断您是否被重定向。此外,试图找出抽象层背后发生的事情是一个坏习惯。

      如果确实需要控制输出,请将日志文件名添加为命令行参数!

      话虽如此,你可以做一些聪明的猜测来找出答案:

      • 程序可以查询 shell 命令历史以找出最近执行的命令。
      • 如果您知道日志文件的路径,则可以扫描该目录并查看文件是否已创建或更改其大小。
      • 重定向和未重定向时的基准写入速度。这只有在您的系统非常稳定且环境条件不会改变时才有效。

      【讨论】:

        【解决方案5】:

        AFAIK 对此的回答是你不能。输出重定向通过简单地从给定程序读取输出流并将其重定向到另一个管道/流来工作。文件/流的设计使得作者对读者一无所知,以至于你不应该知道你正在被阅读。

        即使检测到有一个阅读器也没有用,因为在正常情况下有一个。控制台正在读取程序的输出并将其显示在屏幕上。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-13
          • 2011-06-01
          • 2011-03-28
          • 1970-01-01
          • 1970-01-01
          • 2011-10-19
          • 1970-01-01
          相关资源
          最近更新 更多