2010-12-11 80 views
5

J'écris une application console C# qui prend 2 paramètres: myprogram.exe param1 param2C# - Console.In.ReadToEnd() se bloque sur l'entrée d'utilisateur si aucune donnée passepoilées au programme

param2 est facultative, et l'idée est si ce n'est pas présent, obtenir des données canalisé:

echo "hithere" | myprogram.exe param1 

J'ai fait ce travail partiel en capturant Console.In.ReadToEnd() quand seulement 1 paramètre est passé. Le problème auquel je suis confronté est quand seulement 1 paramètre est passé et aucune donnée n'est canalisée, il se trouve juste là écoutant l'entrée d'utilisateur et la seule manière de fermer est à Ctrl+C pour terminer le programme. Au lieu de cela, existe-t-il un moyen de renvoyer une erreur et de quitter le programme si un seul paramètre a été fourni et qu'aucune donnée n'a été transmise?


Pour tester s'il y a quelque chose d'attente, je l'ai essayé d'utiliser:

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

Cela ne fonctionne pas.

J'ai également essayé le 'hack' mentionné au bas de cette question stackoverflow: C# Console receive input with pipe.

Des idées?

+3

Si vous reformatez votre question pour qu'elle ne ressemble pas à un mur de texte, je pense que vous aurez plus de gens à le lire. –

+0

Je suis d'accord avec Mark, c'est vraiment pénible à lire ... –

+0

Je l'ai reformaté maintenant. J'espère que c'est moins intimidant à lire. – Matt

Répondre

2

Au lieu de vérifier la console, vérifiez la ligne de commande. S'ils transmettent assez d'arguments, alors supposons qu'il n'y a rien à obtenir de la console. Si elles ne spécifient pas suffisamment de paramètres, supposons que l'URL provienne de la console. Vous n'avez pas besoin d'utiliser ReadToEnd(), il suffit d'utiliser ReadLine() à la place afin que vous puissiez aller ligne par ligne. Si vous utilisez ReadToEnd() vous devrez appuyer sur CTRL + Z (ou CTRL + D sous Linux) pour indiquer la fin du flux d'entrée.

+0

Je ne vérifie déjà pas la console.In si elles ont fourni suffisamment de paramètres. N'y a-t-il aucun moyen de détecter si les données ont été redirigées ou non et de quitter immédiatement sans que l'utilisateur n'entre dans CTRL + Z? – Matt

+0

Non, vous avez besoin de l'action de l'utilisateur via une nouvelle ligne (en utilisant 'ReadLine()') ou CTRL + Z (en utilisant 'ReadToEnd()'). –

0

Vous pouvez le programme ci-dessous pour vérifier si standard est redirigée:

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

Utilisation:

bool inputRedirected = ConsoleEx.IsInputRedirected; 

vérifier ensuite le nombre de paramètres de ligne de commande:

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