Проблемы с созданием обработки .NET

У меня есть исполняемый файл, который мгновенно запускается из командной строки, но, похоже, никогда не возвращается, когда создается с помощью 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();
        }

    }   

Возможно, вас заинтересует эта почта, в котором обсуждаются некоторые тонкости работы с процессами .NET таким образом.

ChaseMedallion 16.01.2016 22:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
1
693
3

Ответы 3

Созданный процесс еще жив, пока выполняется WaitForExit ()? Можно к нему отладчик прикрепить?

Он ищет информацию? В частности, я заметил, что вы перенаправляете stdin, но не закрываете его - поэтому, если он читает из stdin, он зависнет.

Ну, закройтесь - stdout vs stdin ;-p

Marc Gravell 16.12.2008 22:00

попробуйте заменить WaitForExit () на что-то вроде этого:

while (!p.WaitForExit(100))
    Console.Write(".");

Еще можно попробовать установить для UseShellExecute значение true и наблюдать за созданием окна консоли. См. Эту страницу, чтобы узнать о тонкостях этого параметра: http://blogs.msdn.com/jmstall/archive/2006/09/28/CreateNoWindow.aspx

Поскольку плакат перенаправляет ввод, я сомневаюсь, что это сработает.

Marc Gravell 16.12.2008 22:08

Другие вопросы по теме