2012-01-25 15 views
20

Estoy escribiendo una aplicación que descarga algunos diagnósticos a la salida estándar.¿Cómo comprobar si el programa se ejecuta desde una consola?

me gustaría tener el trabajo de aplicación de esta manera:

  • Si se ejecuta desde un símbolo del sistema autónomo (a través de cmd.exe) o tiene salida estándar redirigida/entubada a un archivo, salida limpia tan pronto ya que terminó,
  • en caso contrario (si se ejecuta desde una ventana y la ventana de la consola se genera automágicamente), entonces , además, esperar a que pulsar una tecla antes de salir (para permitir al usuario leer los diagnósticos) antes de que desaparezca la ventana

¿Cómo hago esa distinción? Sospecho que examinar el proceso principal podría ser una forma, pero realmente no estoy interesado en WinAPI, de ahí la pregunta.

Estoy en MinGW GCC.

+0

posible duplicado de [? Soy dueño de mi consola o lo heredé de mi padre] (http://stackoverflow.com/questions/6048690/do-i-own-my-console -o-i-inherited-it-from-my-parent) –

Respuesta

19

Puede usar los métodos GetConsoleWindow, GetWindowThreadProcessId y GetCurrentProcessId.

1) En primer lugar debe recuperar el identificador actual de la ventana de la consola usando la función GetConsoleWindow.

2), entonces obtendrá el responsable del proceso de la manija de la ventana de la consola.

3) Finalmente se compara el PID vuelto contra el PID de su aplicación.

Comprobar esta muestra (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

Funciona como un amuleto en todos los casos que pude pensar, en MinGW también. ¡Perfecto gracias! – Kos

+0

Me complace ayudarte, solo ten en cuenta que este método no verifica la redirección de la consola. para eso puedes usar ['GetStdHandle'] (http://msdn.microsoft.com/es-us/library/windows/desktop/ms683231% 28v = vs.85% 29.aspx) y ['GetFileInformationByHandle'] (http://msdn.microsoft.com/en-us/library/windows/desktop /aa364952%28v=vs.85%29.aspx) funciones. – RRUZ

+0

¿No 'GetWindowThreadProcessId' devolverá el ID de CSRSS, no el programa que primero comenzó a ejecutarse en esa ventana? –

3

La prueba típica es:

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

¿Estás seguro de que funciona en Windows? – pezcode

+2

creo que en Windows se '_isatty', declaró en

+0

hace diferencia entre este programa tiene una ventana de la consola de su propia y el programa tiene una ventana de consola que heredó de su proceso padre? –

2

gurú I18N Michael Kaplan de Microsoft proporcionó a series of methods on his blog que permiten comprobar un montón de cosas en la consola, incluyendo si la consola ha sido redirigida.

Están escritos en C#, pero la migración a C o C++ sería muy sencillo, ya que todo se hace con llamadas a la API de Win32.

4

Necesitaba esto en C#. Aquí está la traducción:

[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; 
} 
Cuestiones relacionadas