Soru Programın bir konsoldan çalıştırılıp çalıştırılmadığını nasıl kontrol edebilirim?


Bazı çıktıları standart çıktıya döken bir uygulama yazıyorum.

Uygulamanın bu şekilde çalışmasını istiyorum:

  • Tek başına bir komut isteminden çalıştırılırsa (ile) cmd.exe) veya bir dosyaya yönlendirilmiş / aktarılmış standart çıktıya sahip olduğu anda bittikten sonra temiz bir şekilde çıkacaktır.
  • Aksi takdirde (bir pencereden çalıştırılırsa ve konsol penceresi otomatik olarak ortaya çıkarsa) Ayrıca pencere çıkmadan önce çıkmadan önce bir tuşa basmadan önce (kullanıcının tanılamayı okumasına izin vermek için) bekleyin.

Bu ayrımı nasıl yapabilirim? Ebeveyn sürecini incelemenin bir yol olabileceğinden şüpheleniyorum ama WinAPI'ye gerçekten girmiyorum, dolayısıyla soru.

MinGW GCC'deyim.


21
2018-01-25 19:54


Menşei


olası kopyası Konsolumun sahibi mi yoksa ebeveynimden miras aldım mı? - Rob Kennedy


Cevaplar:


Kullanabilirsiniz GetConsoleWindow, GetWindowThreadProcessId ve GetCurrentProcessId yöntemleri.

1) İlk önce konsol penceresinin geçerli tanıtıcısını GetConsoleWindow işlevi.

2) Ardından konsol penceresinin tanıtıcısının işlem sahibini alırsınız.

3) Sonunda, geri dönen PID'yi uygulamanızın PID'siyle karşılaştırırsınız.

Bu örneği kontrol et (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;
}

20
2018-01-25 20:29



MinGW'de de düşünebildiğim tüm durumlarda bir çekicilik gibi çalışır. Mükemmel teşekkürler! - Kos
Size yardımcı olmaktan memnun oldum, sadece bu yöntemin konsolun yönlendirmesini kontrol etmediğini unutmayın. bunun için kullanabilirsiniz GetStdHandle ve GetFileInformationByHandle fonksiyonlar. - RRUZ
Alışkanlık GetWindowThreadProcessId CSRSS kimliğini döndür, ilk önce o pencerede çalışmaya başlayan programı değil? - Rob Kennedy
Hem Windows hem de Linux üzerinde çalışan başka bir yöntem de "PROMPT" ortam değişkeni elde etmektir. NULL geri dönmezse, konsoldan çalıştırıldınız. Ardından, William Pursell'in cevabında yönlendirme yakalamak için isatty / _isattty yöntemini kullanın; bu, yalnızca Windows olduğunu düşündüğüm GetFileInformationByHandle dosyasındaki başarısızlığı kontrol etmekten daha basittir. - ChocoBilly
@RobKennedy: GetWindowThreadProcessId() işlem kimliğini rapor etmeyecek csrss.exe (ya da conhost.exe). Bu, konsolu yöneten işlem olsa bile nesne ve G / Ç arabellekleri, gerçek konsolu oluşturan işlem değil pencere. - Remy Lebeau


Buna C # 'ya ihtiyacım vardı. İşte çeviri:

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

4
2017-09-10 16:51





Tipik test:

if (isatty (STDOUT_FILENO)) {
        / * bu bir terminaldir * /
}

3
2018-01-25 19:58



Windows'da çalıştığından emin misin? - pezcode
Windows üzerinde düşünüyorum _isatty, <io.h> olarak bildirildi - Drew Dormann
Bu, kendi başına bir konsol penceresi olan program ile ana işleminden miras aldığı bir konsol penceresine sahip program arasında ayrım yapar mı? - Rob Kennedy
Bunun OP'in peşinde olduğunu sanmıyorum, sanırım OP programın mevcut bir terminal penceresinde çalışıp çalışmadığını ya da sadece bir süreç için bir terminal penceresi oluşturup oluşturmayacağını belirlemenin bir yolunu istiyor. - dreamlax
İhtiyacı olanlar için, Windows yolu şudur: if (_isatty (_fileno (stdout))) - ChocoBilly


Microsoft'un I18N gurusu Michael Kaplan sağladı blogunda bir dizi yöntem Konsolun yönlendirilip yönlendirilmediği de dahil olmak üzere konsolda bir sürü şeyi kontrol etmenizi sağlar.

C # ile yazılmıştır, ancak C veya C ++ 'ya taşınıyorlar, hepsi de API API'sı çağrılarıyla yapıldığı için çok kolay olurdu.


2
2018-01-25 20:07