2012-01-25 60 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; 
} 
相關問題