如何检查程序是否在控制台运行?

时间:2022-05-16 00:07:46

I'm writing an application which dumps some diagnostics to the standard output.

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

I'd like to have the application work this way:

我希望申请工作是这样的:

  • If it is run from a standalone command prompt (via cmd.exe) or has standard output redirected/piped to a file, exit cleanly as soon as it finished,
  • 如果它从一个独立的命令提示符(通过cmd.exe)运行,或者将标准输出重定向/管道传输到一个文件,那么在它完成后立即干净地退出,
  • Otherwise (if it is run from a window and the console window is spawned automagically), then additionally wait for a keypress before exiting (to let the user read the diagnostics) before the window disappears
  • 否则(如果从窗口运行,控制台窗口自动生成),那么在窗口消失之前,在退出之前(让用户阅读诊断信息)再等待一个按键

How do I make that distinction? I suspect that examining the parent process could be a way but I'm not really into WinAPI, hence the question.

我怎么区分呢?我怀疑检查父进程可能是一种方法,但我并不真正喜欢WinAPI,因此有了这个问题。

I'm on MinGW GCC.

我在MinGW GCC。

4 个解决方案

#1


20  

You can use GetConsoleWindow, GetWindowThreadProcessId and GetCurrentProcessId methods.

您可以使用GetConsoleWindow、GetWindowThreadProcessId和GetCurrentProcessId方法。

1) First you must retrieve the current handle of the console window using the GetConsoleWindow function.

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

2) Then you get the process owner of the handle of the console window.

然后获取控制台窗口句柄的进程所有者。

3) Finally you compare the returned PID against the PID of your application.

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

Check this sample (VS C++)

检查这个示例(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;
}

#2


4  

I needed this in C#. Here's the translation:

我在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;
}

#3


3  

The typical test is:

典型的测试:

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

#4


2  

I18N guru Michael Kaplan of Microsoft provided a series of methods on his blog that let you check a bunch of things on the console, including whether or not the console has been redirected.

微软(Microsoft)的I18N大师迈克尔•卡普兰(Michael Kaplan)在他的博客上提供了一系列方法,让你可以检查控制台上的一些东西,包括控制台是否被重定向。

They're written in C#, but porting to C or C++ would be very straightforward, as it's all done with calls to the Win32 API.

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

#1


20  

You can use GetConsoleWindow, GetWindowThreadProcessId and GetCurrentProcessId methods.

您可以使用GetConsoleWindow、GetWindowThreadProcessId和GetCurrentProcessId方法。

1) First you must retrieve the current handle of the console window using the GetConsoleWindow function.

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

2) Then you get the process owner of the handle of the console window.

然后获取控制台窗口句柄的进程所有者。

3) Finally you compare the returned PID against the PID of your application.

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

Check this sample (VS C++)

检查这个示例(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;
}

#2


4  

I needed this in C#. Here's the translation:

我在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;
}

#3


3  

The typical test is:

典型的测试:

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

#4


2  

I18N guru Michael Kaplan of Microsoft provided a series of methods on his blog that let you check a bunch of things on the console, including whether or not the console has been redirected.

微软(Microsoft)的I18N大师迈克尔•卡普兰(Michael Kaplan)在他的博客上提供了一系列方法,让你可以检查控制台上的一些东西,包括控制台是否被重定向。

They're written in C#, but porting to C or C++ would be very straightforward, as it's all done with calls to the Win32 API.

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