Antes de seguir adiante com o exemplo, vamos explicar o que é redirecionar a en- trada e saída padrão.
Bem, estes conceitos vêm do velho C e, indo ainda mais longe, do UNIX. Para simplificar, nos tempos em que não se tinham interfaces gráficas como Win- dows, X-Windows etc, quando as interfaces eram textuais, a entrada de dados via teclado era conhecida como entrada padrão (standard input); a saída de da- dos era a saída padrão no vídeo (standard output) e finalmente quando um erro acontecia, este era redirecionado para a saída de erro padrão (standard error). Pois bem, a notícia é que os programas com interface de texto não acabaram e, portanto, os conceitos acima descritos ainda persistem. Você pode estar dizendo que não quer desenvolver nenhum programa DOS e que, sendo assim, vai pular este assunto, mas espere! Pode acontecer que você não queira desenvolver, mas existem centenas de programas extremamente importantes que você pode que- rer executar a partir do Windows e, mais ainda, passar parâmetros e capturar a sua saída. Veja alguns:
m ping m dir m netstat m ipconfig m traceroute
E claro, todos eles são chamados via o intepretador de comandos command.
com, lembra dele?
Como fazemos isso? Primeiro, devemos criar uma instância da classe Pro- cess; em seguida declaramos duas instâncias da classeStreamReaderpara ler a saí- da e erro padrão, e uma instância da classeStreamWriter. Lembrando que usamos essas classes para leitura e escrita de arquivos, e é para esses arquivos que vamos redirecionar a entrada, saída e erro padrão, como fazemos isso? Simples, em lu- gar de digitarmos no teclado, vamos escrever noStreamWriter. A saída e erro pa- drão, que vão para o vídeo, serão redirecionados para um arquivo, no caso o StreamReader, e serão lidos a partir daí. Vejamos o código:
Process p = new Process( ); StreamWriter sw;
StreamReader sr; StreamReader err;
E como a classeProcesssabe que a entrada, saída e erro padrão foram redire- cionados? Ah, boa pergunta, veja: a classeProcess possui uma propriedade cha- madaStartInfo à qual atribuiremos uma instância da classeProcessStartInfo,
que é quem vai fazer todo o trabalho para nós. Essa classe é usada para passar pa- râmetros de inicialização ao processo que vamos iniciar, por exemplo:
m Parâmetros na linha de comando via a propriedade Arguments, como o nome de um arquivo no caso de um compilador de linha de comando.
m Redirecionamento de entrada e saída padrão, conforme mostraremos a
seguir.
m Chamada de programas que usam o interpretador de comandos
command.com, como arquivos batch ou .cmd.
m Etc.
Vejamos:
ProcessStartInfo psI = new ProcessStartInfo("cmd"); // o processo será executado diretamente pelo // programa chamador e não pelo Shell do sistema
psI.UseShellExecute = false; // A entrada padrão é redirecionada
psI.RedirectStandardInput = true; // A saída padrão é redirecionada
psI.RedirectStandardOutput = true; // A saída de erro padrão é redirecionada
psI.RedirectStandardError = true;
// Dissemos ao Windows para não criar uma janela // para o processo
psI.CreateNoWindow = true;
// e finalmente definimos a propriedade StartInfo da classe //Process
p.StartInfo = psI;
Observe que criamos uma instância da classeProcessStartInfo e no seu construtor passamos o nome do programa que desejamos iniciar, que no nosso caso é o interpretador de comandos do Windows (o falecido command.com). Em seguida definimos algumas das suas propriedades conforme explicado nos comentários do código acima. Além disso, se você observar o código, ago- ra estamos criando uma instância da classe Process, chamando o método Start( ) e estamos passando parâmetros via a instância da classe Process- StartInfo. Por sua vez, no exemplo anterior, chamamos o método estático Start(Par), passando como parâmetro o nome do arquivo do programa que
Se modificarmos alguma das propriedades da classeProcessStartInfo de- pois de a termos atribuído ao componente Process, essas modificações não terão nenhum efeito!
Agora chamamos as propriedades da classe Process, StandardInput,Stan- dardErroreStandardOutputque retornarão os respectivos descritores de arquivo para podermos ler a entrada e erro padrão, assim como escrever na saída. Veja- mos:
sw = p.StandardInput; sr = p.StandardOutput;
err = p.StandardError;
/* Definimos a propriedade AutoFlush = true para que o buffer de escrita seja descarregado automaticamente na saída padrão que foi redirecionada para o arquivo físico representado pelo StreamWriter sw.
*/
sw.AutoFlush = true;
E como escrever na entrada padrão? Uma operação de escrita no StreamWri- ter resolve o problema. Veja:
if (tbComm.Text != "") sw.WriteLine(tbComm.Text); else
//execute commando default sw.WriteLine("dir \\"); sw.Close( );
Agora vamos ler a saída e erros padrão da mesma forma como lemos um ar- quivo:
textBox1.Text = sr.ReadToEnd( ); textBox1.Text += err.ReadToEnd( ); sr.Close( );
err.Close( );
Mas, de repente, você apenas quer executar uma aplicação do DOS a partir de uma aplicação C#, mas sem necessidade de redirecionar a entrada e saída pa- drão. Não tem problema, o código a seguir mostra como:
Process p = new Process( );
ProcessStartInfo psI = new ProcessStartInfo( ); psI.FileName = "dir /p";
psI.UseShellExecute = true; // Tem de ser verdadeiro quando o programa em questão será executado pelo Shell.
p.StartInfo = psI;
p.Start( ); // Executa o comando
Vamos tentar entender o que estamos fazendo no código acima: 1. Criamos uma instância da classeProcesseProcessStartInfo.
2. Na propriedadeFileNameda instância da classe ProcessStartInfo, atri- buímos o nome do comando DOS ou arquivo batch que desejamos exe- cutar.
3. A propriedadeUseShellExecuteda instância da classeProcessStartInfo deve ter o valortrue, porque comandos internos e arquivos batch são executados através do shell (interpretador de comandos) do sistema. 4. Atribuimos à propriedade StartInfo da classe Process a instância de
ProcessStartInfo e executamos o método Start( ) da classe Process que executará o comando DOS ou arquivobatch.