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

Kos*_*Kos 24 c c++ winapi

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

我想让应用程序以这种方式工作:

  • 如果它是从独立命令提示符(通过cmd.exe)运行或将标准输出重定向/管道传输到文件,请在完成后立即退出,
  • 否则(如果它是从一个窗口运行并且控制台窗口是自动生成的),那么在窗口消失之前还要等待一个按键才能退出(让用户读取诊断信息)

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

我在MinGW海湾合作委员会.

RRU*_*RUZ 24

您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

  • 另一种适用于Windows和Linux的方法是获取环境变量"PROMPT".如果它没有返回NULL,则从控制台运行.然后使用isatty/_isattty方法捕获William Pursell的答案中的重定向,这比从GetFileInformationByHandle检查失败更简单,我认为这只是Windows. (3认同)
  • @RobKennedy:GetWindowThreadProcessId()不会报告csrss.exe(甚至conhost.exe)的进程ID。即使那是管理控制台* object *及其I / O缓冲区的过程,也不是创建实际控制台* window *的过程。 (2认同)

Wil*_*ell 6

典型的测试是:

if( isatty( STDOUT_FILENO )) {
        /* 这是一个终端 */
}

  • 我认为在 Windows 上它是 `_isatty`,在 &lt;io.h&gt; 中声明 (3认同)

小智 6

我在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;
}
Run Code Online (Sandbox Code Playgroud)