C # Console receber a entrada com a tubulação
Pergunta
Eu sei como programar aplicativo Console com parâmetros, como por exemplo:. MyProgram.EXE param1 param2
A minha pergunta é, como posso fazer meus programa trabalha com |, exemplo: echo "palavra" | MyProgram.EXE?
Solução
Você precisa usar Console.Read()
e Console.ReadLine()
como se estivesse lendo a entrada do usuário. Pipes substituir a entrada do usuário de forma transparente. Você não pode usar ambos facilmente (embora eu tenho certeza que é bem possível ...).
Editar:
Um programa simples estilo cat
:
class Program
{
static void Main(string[] args)
{
string s;
while ((s = Console.ReadLine()) != null)
{
Console.WriteLine(s);
}
}
}
E quando executado, como esperado, a saída:
C:\...\ConsoleApplication1\bin\Debug>echo "Foo bar baz" | ConsoleApplication1.exe "Foo bar baz" C:\...\ConsoleApplication1\bin\Debug>
Outras dicas
O seguinte não irá suspender o pedido de entrada e obras quando os dados é ou não é canalizada. Um pouco de um truque; e devido ao erro de captura, o desempenho poderia faltar quando várias chamadas canalizada são feitas, mas ... fácil.
public static void Main(String[] args)
{
String pipedText = "";
bool isKeyAvailable;
try
{
isKeyAvailable = System.Console.KeyAvailable;
}
catch (InvalidOperationException expected)
{
pipedText = System.Console.In.ReadToEnd();
}
//do something with pipedText or the args
}
em .NET 4.5 a sua
if (Console.IsInputRedirected)
{
using(stream s = Console.OpenStandardInput())
{
...
Esta é a maneira de fazê-lo:
static void Main(string[] args)
{
Console.SetIn(new StreamReader(Console.OpenStandardInput(8192))); // This will allow input >256 chars
while (Console.In.Peek() != -1)
{
string input = Console.In.ReadLine();
Console.WriteLine("Data read was " + input);
}
}
Isto permite dois métodos de uso. Leia a partir de entrada padrão :
C:\test>myProgram.exe
hello
Data read was hello
ou ler entrada canalizada :
C:\test>echo hello | myProgram.exe
Data read was hello
Aqui é uma outra solução alternativa que foi colocado junto das outras soluções, mais uma espiada ().
Sem o Peek () eu estava experimentando que o aplicativo não voltaria sem ctrl-c no final, quando a fazer "tipo t.txt | Prog.exe" onde t.txt é um arquivo multi-line. Mas apenas "Prog.exe" ou "eco oi | Prog.exe". Funcionou bem
este código é utilizado para único processo encanada de entrada.
static int Main(string[] args)
{
// if nothing is being piped in, then exit
if (!IsPipedInput())
return 0;
while (Console.In.Peek() != -1)
{
string input = Console.In.ReadLine();
Console.WriteLine(input);
}
return 0;
}
private static bool IsPipedInput()
{
try
{
bool isKey = Console.KeyAvailable;
return false;
}
catch
{
return true;
}
}
Console.In é uma referência a um TextReader enrolada em torno do fluxo de entrada padrão. Quando tubulação grandes quantidades de dados para o seu programa, pode ser mais fácil trabalhar com essa maneira.
existe um problema com o exemplo fornecido.
while ((s = Console.ReadLine()) != null)
será espera preso para a entrada se o programa foi lançado sem dados canalizado. assim o usuário tem que pressionar manualmente qualquer tecla para programa de saída.
Esta será também trabalho para
c: \ MyApp.exe
Eu tive que usar um StringBuilder para manipular as entradas capturados de Stdin:
public static void Main()
{
List<string> salesLines = new List<string>();
Console.InputEncoding = Encoding.UTF8;
using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding))
{
string stdin;
do
{
StringBuilder stdinBuilder = new StringBuilder();
stdin = reader.ReadLine();
stdinBuilder.Append(stdin);
var lineIn = stdin;
if (stdinBuilder.ToString().Trim() != "")
{
salesLines.Add(stdinBuilder.ToString().Trim());
}
} while (stdin != null);
}
}