2012-01-25 4 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, GetWindowThreadProcessId и GetCurrentProcessId методов.

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/en-us/library/windows/desktop /aa364952%28v=vs.85%29.aspx). – RRUZ

+0

Не будет 'GetWindowThreadProcessId' вернуть идентификатор CSRSS, а не программу, которая впервые запустилась в этом окне? –

3

Типичный тест:

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

Вы уверены, что работает в Windows? – pezcode

+2

Я думаю, что в Windows это '_isatty', объявлено в

+0

Различия между программой, имеющей собственное консольное окно, и программой, имеющей окно консоли, которое оно унаследовало от своего родительского процесса? –

2

I18N гуру Майкл Каплан из Microsoft при условии a series of methods on his blog что позволит вам проверить кучу вещей на консоли, в том числе, был ли или не был перенаправлен на консоли.

Они написаны на C#, но перенос на C или C++ был бы очень прост, так как все это делается с вызовами API Win32.

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; 
} 
Смежные вопросы