C++ 如何检查程序是否从控制台运行?

C++ 如何检查程序是否从控制台运行?,c++,c,winapi,C++,C,Winapi,我正在编写一个应用程序,它将一些诊断转储到标准输出 我希望通过以下方式进行申请: 如果从独立命令提示符(通过cmd.exe)运行,或将标准输出重定向/通过管道传输到文件,请在完成后立即退出 否则(如果从窗口运行,并且控制台窗口自动生成),则 另外,在退出前等待按键(让用户读取诊断),然后窗口消失 我如何区分?我怀疑检查父进程可能是一种方法,但我并不真正喜欢WinAPI,因此我提出了这个问题 我在MinGW GCC上。典型的测试是: if( isatty( STDOUT_FILENO )) {

我正在编写一个应用程序,它将一些诊断转储到标准输出

我希望通过以下方式进行申请:

  • 如果从独立命令提示符(通过
    cmd.exe
    )运行,或将标准输出重定向/通过管道传输到文件,请在完成后立即退出
  • 否则(如果从窗口运行,并且控制台窗口自动生成),则 另外,在退出前等待按键(让用户读取诊断),然后窗口消失
我如何区分?我怀疑检查父进程可能是一种方法,但我并不真正喜欢WinAPI,因此我提出了这个问题

我在MinGW GCC上。

典型的测试是:

if( isatty( STDOUT_FILENO )) { /* this is a terminal */ } if(isatty(标准文件号)){ /*这是终点站*/ }
微软的I18N大师迈克尔·卡普兰(michaelkaplan)提供了一个功能,可以让你检查控制台上的很多事情,包括控制台是否被重定向

它们是用C语言编写的,但是移植到C或C++会很简单,因为所有的调用都是Win32 API。

,可以使用方法。 1) 首先,必须使用
GetConsoleWindow
函数检索控制台窗口的当前句柄

2) 然后获得控制台窗口句柄的进程所有者

3) 最后,将返回的PID与应用程序的PID进行比较

检查此示例(VS C++)

#包括“stdafx.h”
#包括
使用名称空间std;
#如果_WIN32_WINNT<0x0500
#undef\u WIN32\u WINNT
#定义_WIN32_WINNT 0x0500
#恩迪夫
#包括
#包括“Wincon.h”
int _tmain(int argc,_TCHAR*argv[]
{   
HWND consoleWnd=GetConsoleWindow();
DWORD dwProcessId;
GetWindowThreadProcessId(控制台EWND和dwProcessId);
if(GetCurrentProcessId()==dwProcessId)
{
可以我需要C#中的这个。下面是翻译:

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcessId();

[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(IntPtr hWnd, ref IntPtr ProcessId);

static int Main(string[] args)
{
    IntPtr hConsole = GetConsoleWindow();
    IntPtr hProcessId = IntPtr.Zero;
    GetWindowThreadProcessId(hConsole, ref hProcessId);

    if (GetCurrentProcessId().Equals(hProcessId))
    {
        Console.WriteLine("I have my own console, press any key to exit");
        Console.ReadKey();
    }
    else
        Console.WriteLine("This console is not mine, good bye");

    return 0;
}

在尝试了许多不同的api和调用之后,我发现只有一种可行的方法:

bool isConsole = isatty(fileno(stdin));

Stdout不能使用,因为您可以使用
>log.txt
开关运行控制台应用程序并将输出重定向到文件。请怀疑它也可以重定向输入,但在运行控制台应用程序时很少使用它的功能。

我认为在Windows上它是
\u isatty
,在中声明,这是否区分了betwe程序有自己的控制台窗口,程序有从父进程继承的控制台窗口?我不认为这是OP所追求的,我认为OP想要一种方法来确定程序是否在现有的终端窗口中运行,或者终端窗口是否只是为进程生成的需要它的Windows方式是:if(_isatty(_fileno(stdout)))当您使用控制台并将输出重定向到文件时,不起作用。在我能想到的所有情况下,在MinGW上,可能的重复都像一个符咒一样起作用。非常好,谢谢!很高兴帮助您,请注意此方法不会检查控制台的重定向。为此,您可以使用和函数。不会
GetWindowThreadProcessId
return是CSRSS的ID,而不是第一次在该窗口中运行的程序?另一种在Windows和Linux上都有效的方法是获取环境变量“PROMPT”。如果没有返回NULL,则从控制台运行。然后使用isatty/_isattty方法捕获William Pursell答案中的重定向,这比从GetFileInformationByHandle(我认为仅限Windows)检查失败要简单。@RobKennedy:
GetWindowThreadProcessId()
不会报告
csrss.exe
(甚至是
conhost.exe
)的进程ID。即使这是管理控制台对象及其I/O缓冲区的进程,也不是创建实际控制台窗口的进程。
bool isConsole = isatty(fileno(stdin));