2010-12-11 14 views
5

Piszę aplikację konsoli C#, który trwa 2 parametry: myprogram.exe param1 param2C# - Console.In.ReadToEnd() zawiesza się na danych wprowadzonych przez użytkownika, jeśli nie ma danych rurami zaprogramować

param2 jest opcjonalny, a chodzi o to, czy to nie jest obecny, uzyskać dane rurami:

echo "hithere" | myprogram.exe param1 

zrobiłem to praca w niepełnym wymiarze poprzez przechwytywanie Console.In.ReadToEnd() gdy tylko 1 parametr jest przekazywana.

Problem, przed którym stoję, to sytuacja, w której przekazywany jest tylko jeden parametr i żadne dane nie są przesyłane, po prostu siedzi tam, słuchając danych wprowadzanych przez użytkownika, a jedynym sposobem zamknięcia jest Ctrl+C, aby zakończyć program.

Zamiast tego, czy istnieje sposób na zwrócenie błędu i wyjście z programu, jeśli podano tylko jeden parametr i nie wysłano żadnych danych?


Aby sprawdzić, czy jest coś czeka, próbowałem przy użyciu:

  • Console.OpenStandardInput().CanRead
  • Console.OpenStandardInput().Length
  • Console.In.Peek()

To nie działa.

Próbowałem również "hack" wymienionych na dole tego pytanie stackoverflow: C# Console receive input with pipe.

Wszelkie pomysły?

+3

Jeśli ponownie sformatujesz pytanie, aby nie wyglądało to jak ściana tekstu, myślę, że dostaniesz więcej ludzi do przeczytania. –

+0

Zgadzam się z Markiem, naprawdę trudno jest przeczytać ... –

+0

Sformatowałem to teraz. Mam nadzieję, że nie będzie to trudniejsze do odczytania. – Matt

Odpowiedz

2

Zamiast sprawdzać konsolę, sprawdź wiersz polecenia. Jeśli przejdą wystarczającą liczbę argumentów, załóżmy, że nie ma nic do zdobycia z konsoli. Jeśli nie podadzą wystarczającej liczby parametrów, przyjmiemy, że URL pochodzi z konsoli. Nie musisz używać ReadToEnd(), wystarczy użyć ReadLine(), aby można było przejść linię po linii. Jeśli użyjesz ReadToEnd(), musisz nacisnąć CTRL + Z (lub CTRL + D w linuksie), aby wskazać koniec strumienia wejściowego.

+0

Już nie sprawdzam konsoli. Jeśli dostarczono wystarczającą liczbę parametrów. Czy nie ma sposobu, aby wykryć, czy dane zostały wyprowadzone, czy nie i natychmiast wyjść, bez wpisywania CTRL + Z? – Matt

+0

Nie, potrzebujesz użytkownika do działania poprzez znak nowej linii (używając 'ReadLine()') lub CTRL + Z (używając 'ReadToEnd()'). –

0

Mogłeś następujący program aby sprawdzić, czy standard jest przekierowywany:

using System; 
using System.Runtime.InteropServices; 

public static class ConsoleEx { 
    public static bool IsOutputRedirected { 
    get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdout)); } 
    } 
    public static bool IsInputRedirected { 
    get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdin)); } 
    } 
    public static bool IsErrorRedirected { 
    get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stderr)); } 
    } 

    // P/Invoke: 
    private enum FileType { Unknown, Disk, Char, Pipe }; 
    private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 }; 
    [DllImport("kernel32.dll")] 
    private static extern FileType GetFileType(IntPtr hdl); 
    [DllImport("kernel32.dll")] 
    private static extern IntPtr GetStdHandle(StdHandle std); 
} 

Zastosowanie:

bool inputRedirected = ConsoleEx.IsInputRedirected; 

Następnie sprawdzić liczbę parametrów wiersza polecenia:

if (args.Length < 1) 
# No parameters were passed 
if (args.Length < 2) 
{ 
    if (!inputRedirected) 
    { 
     Console.Error.WriteLine("You must redirect from stdin"); 
     # exit/die/end here 
    } 
} 
Powiązane problemy