Questo dovrebbe funzionare. Potresti provare a scaricare il contenuto dell'output e i flussi di errore per scoprire cosa sta succedendo:
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");
}
* MODIFICARE *
Date le informazioni extra nel tuo commento qui sotto, sono stato in grado di ricreare il problema. Sembra esserci qualche impostazione di sicurezza che provoca questo comportamento (non l'ho studiato in dettaglio).
Questo fa il lavoro se il file batch non si trova in C:\Windows\System32
. Prova a spostarlo in un'altra posizione, ad esempio la posizione del tuo eseguibile. Si noti che mantenere file batch o eseguibili personalizzati nella directory di Windows è comunque una cattiva pratica.
* EDIT 2 *
Si scopre che se i flussi vengono letti in modo sincrono, può verificarsi un deadlock, leggendo in modo sincrono prima WaitForExit
o leggendo entrambi stderr
e in modo stdout
sincrono uno dopo l'altro.
Ciò non dovrebbe accadere se si utilizzano invece i metodi di lettura asincroni, come nell'esempio seguente:
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
sia. Se contiene percorsi con spazi, dovrai inserire delle virgolette attorno ad essi.