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 WaitForExitou lendo tanto stderre stdoutde 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.