2012-01-25 81 views
20

我在写一个应用程序,它将一些诊断信息转储到标准输出。如何检查程序是否从控制台运行?

我想有应用的工作是这样的:

  • 如果它是从一个独立的命令提示符下运行(通过cmd.exe)或尽快干净拥有标准输出重定向/管道到一个文件,退出因为它完成,
  • 否则(如果它是从一个窗口中运行,并在控制台窗口是自动生成),然后 额外等待一个按键退出之前(让用户读取诊断)窗口消失

我该如何作出区分? 我怀疑检查父进程可能是一种方式,但我并不真正进入WinAPI,因此是一个问题。

我在MinGW GCC上。

+0

可能重复[?我拥有我的控制台或我继承了它从我的父母(http://stackoverflow.com/questions/6048690/do-i-own-my-console -or-i-inherited-it-from-my-parent) –

回答

19

您可以使用GetConsoleWindow,GetWindowThreadProcessIdGetCurrentProcessId方法。

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

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

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

检查该样品(VS C++)

#include "stdafx.h" 
#include <iostream> 
using namespace std; 
#if  _WIN32_WINNT < 0x0500 
    #undef _WIN32_WINNT 
    #define _WIN32_WINNT 0x0500 
#endif 
#include <windows.h> 
#include "Wincon.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HWND consoleWnd = GetConsoleWindow(); 
    DWORD dwProcessId; 
    GetWindowThreadProcessId(consoleWnd, &dwProcessId); 
    if (GetCurrentProcessId()==dwProcessId) 
    { 
     cout << "I have my own console, press enter to exit" << endl; 
     cin.get(); 
    } 
    else 
    { 
     cout << "This Console is not mine, good bye" << endl; 
    } 


    return 0; 
} 
+0

在MinGW上我可以想到所有情况下的魅力。很好,谢谢! – Kos

+0

很高兴为您提供帮助,请注意这种方法不检查控制台的重定向。为此你可以使用['GetStdHandle'](http://msdn.microsoft。com/en-us/library/windows/desktop/ms683231%28v = vs.85%29.aspx)和['GetFileInformationByHandle'](http://msdn.microsoft.com/zh-cn/library/windows/desktop /aa364952%28v=vs.85%29.aspx)函数。 – RRUZ

+0

GetWindowThreadProcessId不会返回CSRSS的ID,而不是最先开始在该窗口中运行的程序? –

3

典型的测试是:微软的

 
if(isatty(STDOUT_FILENO)) { 
     /* this is a terminal */ 
} 
+0

您确定可以在Windows上使用吗? – pezcode

+2

我认为在Windows上它是'_isatty',在

+0

中声明这是否区分具有自己的控制台窗口的程序和具有从其父进程继承的控制台窗口的程序? –

2

国际化大师迈克尔·卡普兰提供a series of methods on his blog,让你检查了一堆东西在控制台上,包括控制台是否已被重定向。

它们是用C#编写的,但移植到C或C++会非常简单,因为它都是通过调用Win32 API完成的。

4

我在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; 
} 
相关问题