У меня есть исполняемый файл, который мгновенно запускается из командной строки, но, похоже, никогда не возвращается, когда создается с помощью System.Diagnostics.Process:
По сути, я пишу оболочку библиотеки .NET для интерфейса CLI Accurev, поэтому каждый вызов метода порождает процесс CLI для выполнения команды.
Это отлично работает для всех команд, кроме одной:
accurev.exe show depots
Однако при запуске этого с консоли он работает нормально, когда я вызываю его с помощью процесса .net, он зависает ... Код порождения процесса, который я использую, следующий:
public static string ExecuteCommand(string command)
{
Process p = createProcess(command);
p.Start();
p.WaitForExit();
// Accurev writes to the error stream if ExitCode is non zero.
if (p.ExitCode != 0)
{
string error = p.StandardError.ReadToEnd();
Log.Write(command + " failed..." + error);
throw new AccurevException(error);
}
else
{
return p.StandardOutput.ReadToEnd();
}
}
/// Creates Accurev Process
/// </summary>
/// <param name = "command"></param>
/// <returns></returns>
private static Process createProcess(string command)
{
Log.Write("Executing Command: " + command);
ProcessStartInfo startInfo = new ProcessStartInfo();
Process p = new Process();
startInfo.CreateNoWindow = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.Arguments = command;
startInfo.FileName = _accurev;
p.StartInfo = startInfo;
return p;
}
Зависает при p.WaitForExit ().
Любой совет?
РЕДАКТИРОВАТЬ: Решено!
.NET Process зависает при переполнении буфера вывода, я перешел на асинхронный метод чтения, и все работает:
public static string ExecuteCommand(string command)
{
StringBuilder outputData = new StringBuilder();
Process p = createProcess(command);
p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
outputData.AppendLine(e.Data);
};
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
// Accurev writes to the error stream if ExitCode is non zero.
if (p.ExitCode != 0)
{
string error = p.StandardError.ReadToEnd();
Log.Write(command + " failed..." + error);
throw new AccurevException(error);
}
else
{
return outputData.ToString();
}
}





Созданный процесс еще жив, пока выполняется WaitForExit ()? Можно к нему отладчик прикрепить?
Он ищет информацию? В частности, я заметил, что вы перенаправляете stdin, но не закрываете его - поэтому, если он читает из stdin, он зависнет.
Ну, закройтесь - stdout vs stdin ;-p
попробуйте заменить WaitForExit () на что-то вроде этого:
while (!p.WaitForExit(100))
Console.Write(".");
Еще можно попробовать установить для UseShellExecute значение true и наблюдать за созданием окна консоли. См. Эту страницу, чтобы узнать о тонкостях этого параметра: http://blogs.msdn.com/jmstall/archive/2006/09/28/CreateNoWindow.aspx
Поскольку плакат перенаправляет ввод, я сомневаюсь, что это сработает.
Возможно, вас заинтересует эта почта, в котором обсуждаются некоторые тонкости работы с процессами .NET таким образом.