2011-06-20 21 views
15

Ive niektóre kod biblioteki, który jest używany przez aplikacje konsoli i wpf. W kodzie biblioteki jest kilka połączeń Console.Read(). Chcę tylko odczytać te dane wejściowe, jeśli aplikacja jest aplikacją konsolową, jeśli nie jest to aplikacja GUI - jak powiedzieć w dll, czy aplikacja ma konsolę?Jak sprawdzić, czy jest konsola?

+0

[W jaki sposób aplikacja konsoli C# dla systemu Windows może powiedzieć, czy jest uruchamiana interaktywnie] (http://stackoverflow.com/a/8711036/344541) –

+0

Mój komentarz jest linkiem - przepraszam za zamieszanie. –

+0

Możliwy duplikat [W jaki sposób aplikacja konsoli systemu Windows może podpowiedzieć, czy jest uruchamiana interaktywnie] (http://stackoverflow.com/questions/1188658/how-can-ac-sharp-windows-console-application-tell-if- it-run-run-interactively) –

Odpowiedz

15

W końcu zrobiłem następująco:

// Property: 
private bool? _console_present; 
public bool console_present { 
    get { 
     if (_console_present == null) { 
      _console_present = true; 
      try { int window_height = Console.WindowHeight; } 
      catch { _console_present = false; } 
     } 
     return _console_present.Value; 
    } 
} 

//Usage 
if (console_present) 
    Console.Read(); 

Po thekips porady ja dodany człon delegować klasy biblioteki, aby uzyskać walidację użytkownika - i ustawić na domyślny implimentation który używa powyżej, aby sprawdzić, czy Teresy konsola i jeśli obecna używa tego, aby uzyskać walidację użytkownika lub nic nie robi, jeśli nie (akcja idzie do przodu bez sprawdzania poprawności użytkownika). Oznacza to:

  1. Wszystkie istniejące klienty (aplikacje wiersza poleceń, usługi systemu Windows (bez interakcji użytkownika), aplikacje wpf) działają bez zmian.
  2. Dowolna aplikacja bez konsoli, która wymaga danych wejściowych, może po prostu zastąpić domyślną funkcję delegowania inną weryfikacją (GUI - msg box etc).

Dziękuję wszystkim, którzy odpowiedzieli.

+0

Używanie "catch catch" to nie jest dobra praktyka –

5

Powinieneś to poprawić w swoim projekcie. Jest to dobry przykład miejsca, w którym odwrócenie kontroli byłoby bardzo przydatne. Ponieważ kod wywołujący jest świadomy tego, który interfejs jest dostępny, ten kod powinien na przykład określać przykład interfejsu IInputReader. W ten sposób możesz użyć tego samego kodu dla wielu scenariuszy uzyskiwania danych wejściowych od użytkownika.

+0

Dziękuję - jestem świadomy, że jest to wada projektowa - a Twoja sugestia jest właściwym sposobem, aby to naprawić - ale ten konkretny przypadek w tej chwili nie uzasadnia poprawnego przeprojektowania - po prostu chcę wyłączyć proste czytanie konsoli. – Ricibob

+0

W takim przypadku możesz po prostu użyć właściwości ustawionej w interfejsie użytkownika? IsConsole i używać logiki Boole'a? – thekip

0

jeśli chcesz dobry projekt, streszczenie zależności GUI za pomocą interfejsu. Implementuje konkretną klasę dla wersji konsolowej, inną dla wersji WPF i wstrzykuje poprawną wersję w dowolny sposób (wstrzyknięcie zależności, odwrócenie kontroli itp.).

3

Możesz przekazać argument o inicjalizacji.

na przykład:

w klasie biblioteki dodać konstruktora z parametrem „IsConsole”.

public YourLibrary(bool IsConsole) 
{ 
    if (IsConsole) 
    { 
    // Do console work 
    } 
    else 
    { 
    // Do wpf work 
    } 
} 

A z konsoli można użyć:

YourLibrary lib = new YourLibrary(true); 

Form WPF:

YourLibrary lib = new YourLibrary(false); 
1

This SO question może dostarczyć Ci jakieś rozwiązanie ...

Innym rozwiązaniem jest:

Console.Read() zwraca -1 w aplikacji formularza Windows bez otwierania okna konsoli. W aplikacji konsoli zwraca rzeczywistą wartość. Możesz więc napisać coś takiego, jak: Testowałem ten kod na konsolach i aplikacjach WinForm. W aplikacji konsolowej, jeśli użytkownik wprowadza "-1 ', wartość j wynosi . Więc to zadziała.

+1

Dzięki - ale muszę wiedzieć przy starcie aplikacji i nie chcę teraz wymagać danych wejściowych z konsoli (iw konsoli aplikacji Console.Read to zrobi). Również w wpf Console.Read powoduje zawieszenie (lub wyjątek w zależności od tego, kiedy zostanie wywołany). – Ricibob

5

Można użyć tego kodu:

public static bool HasMainWindow() 
{ 
    return (Process.GetCurrentProcess().MainWindowHandle != IntPtr.Zero); 
} 

działało dobrze z szybkiego testu na konsoli vs. aplikacji WinForms.

+0

Dzięki - jest to rodzaj odpowiedzi, której potrzebowałem - niestety dla mnie jest to prawda zarówno dla konsoli, jak i aplikacji wpf .. :-( – Ricibob

+0

@Rici to dziwne .. moja konsola testowa zwraca zwykły "false" - jak dokładnie budujesz ta aplikacja konsolowa? Jak to działa? –

+0

@Shadow Wizard: Pamiętaj, że kod znajduje się w bibliotece DLL - klient jest zwyczajną aplikacją konsolową. Zamieszczam poniżej odpowiedź, która działa dla mnie - raczej krucha, ale dostaję pracę zrobione - które w tej chwili jest wszystkim, czego potrzebuję! – Ricibob

11

Pracuj dla mnie (za pomocą metody natywnej)

pierwsze, oświadczam:

[DllImport("kernel32.dll")] 
    static extern IntPtr GetConsoleWindow(); 

Po sprawdzić z elegancją ... hahaha ...:

if (GetConsoleWindow() != IntPtr.Zero) 
{ 
    Console.Write("has console"); 
} 
10
if (Environment.UserInteractive) 
{ 
    // A console is opened 
} 

Zobacz: http://msdn.microsoft.com/en-us/library/system.environment.userinteractive(v=vs.110).aspx

Pobiera wartość wskazującą, czy bieżący proces jest uruchomiony w trybie interaktywnym użytkownika.

+2

Działa dla odróżnienia serwera Windows od aplikacji konsola/wpf, ale nie identyfikuje konsoli, tj. Nie rozróżnia między konsolą a wpf. – Ricibob

+0

Prawidłowo, usługi mogą działać w trybie interaktywnym w systemach Windows, tak było przez długi czas. W przypadku prostej aplikacji komputerowej ta metoda może być akceptowalna. Jeśli piszesz kod, który może działać w procesie Windows, a także na pulpicie (takim jak kod logowania), ta metoda może mieć niezamierzone konsekwencje (takie jak marnowanie cykli zapisywania danych wyjściowych konsoli podczas działania jako usługa). –

1

przepisałem @ Ricibob za odpowiedź

public bool console_present { 
    get { 
     try { return Console.WindowHeight > 0; } 
     catch { return false; } 
    } 
} 

//Usage 
if (console_present) { Console.Read(); } 

To jest prostsze, ale wolę to rodzimy realizacji:

[DllImport("kernel32.dll")] 
static extern IntPtr GetConsoleWindow(); 

//Usage 
if (GetConsoleWindow()) { Console.Read(); } 
0
var isReallyAConsoleWindow = Environment.UserInteractive && Console.Title.Length > 0; 

Połączenie Environment.UserInteractive i Console.Title.Length powinien dać właściwą odpowiedź na pytanie o okno konsoli. Jest to proste i proste rozwiązanie.

Powiązane problemy