Isso deve funcionar. Você pode tentar despejar o conteúdo dos fluxos de saída e erro para descobrir o que está acontecendo:
static void ExecuteCommand(string command)
{
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
// Warning: This approach can lead to deadlocks, see Edit #2
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
static void Main()
{
ExecuteCommand("echo testing");
}
* EDIT *
Dadas as informações extras em seu comentário abaixo, consegui recriar o problema. Parece haver alguma configuração de segurança que resulta nesse comportamento (não a investigamos em detalhes).
Isso faz trabalho se o arquivo de lote não está localizado em C:\Windows\System32
. Tente movê-lo para outro local, por exemplo, o local do seu executável. Observe que manter os arquivos em lotes personalizados ou executáveis no diretório do Windows é uma prática recomendada de qualquer maneira.
* EDIT 2 *
Ele gira para fora que, se os fluxos são lidos de forma síncrona, um impasse pode ocorrer, quer através da leitura de forma síncrona antes WaitForExit
ou lendo tanto stderr
e stdout
de forma síncrona um após o outro.
Isso não deve acontecer se você usar os métodos de leitura assíncrona, como no exemplo a seguir:
static void ExecuteCommand(string command)
{
var processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
var process = Process.Start(processInfo);
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
Console.WriteLine("output>>" + e.Data);
process.BeginOutputReadLine();
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
Console.WriteLine("error>>" + e.Data);
process.BeginErrorReadLine();
process.WaitForExit();
Console.WriteLine("ExitCode: {0}", process.ExitCode);
process.Close();
}
command
é. Se ele contiver caminhos com espaços, você precisará colocar aspas em torno deles.