Альтернативный нативный API для Process.Start - PullRequest
2 голосов
/ 13 апреля 2010

Хорошо, это не дубликат " Альтернатива Process.Start () ", потому что мой вопрос здесь совсем другой.

Мне нужно запустить процесс и дождаться его выполнения и получить вывод консоли.

Существует способ установить для RedirectStandardOutput и RedirectStandardError значение true, однако на некоторых машинах это работает некорректно (где не установлен .NET SDK), установлена ​​только среда выполнения .NET, теперь она работает на некоторых машинах и не работает на некоторых машинах, поэтому мы не знаем, в чем проблема.

У меня следующий код,

        ProcessStartInfo info = new ProcessStartInfo("myapp.exe", cmd);
        info.CreateNoWindow = true;
        info.UseShellExecute = false;
        info.RedirectStandardError = true;
        info.RedirectStandardOutput = true;
        Process p =  Process.Start(info);
        p.WaitForExit();
        Trace.WriteLine(p.StandardOutput.ReadToEnd());
        Trace.WriteLine(p.StandardError.ReadToEnd());

На некоторых машинах это будет зависать навсегда на p.WaitForExit (), а на некоторых машинах он работает правильно, поведение настолько случайное и никакой подсказки.

Теперь, если я смогу найти действительно хороший обходной путь для этого с помощью pinvoke, я буду очень счастлив.

myapp.exe - это не что иное, как написание 10 приветственных утверждений на экране.

Ответы [ 3 ]

1 голос
/ 13 апреля 2010

Может ли быть так, что ваш дочерний процесс действительно зависает навсегда, например. ожидание ввода или отображение диалогового окна с сообщением об ошибке, которое не отображается?

Нативным API является CreateProcess , и оно соответствует pInvoke .

0 голосов
/ 24 мая 2010

Хорошо, я получил этот ответ откуда-то ...

    using System.Diagnostics;
    using System.Threading;

    ProcessStartInfo info = new ProcessStartInfo("myapp.exe", cmd); 
    info.CreateNoWindow = true; 
    info.UseShellExecute = false; 
    info.RedirectStandardError = true; 
    info.RedirectStandardOutput = true; 
    Process p =  new Process();
    p.StartInfo = info; 
    p.BeginOutputReadLine();
    p.BeginErrorReadLine();

    AutoResetEvent wait = new AutoResetEvent(false);

    p.Exited += (s,e)=>{
        wait.Set();
    }
    p.Start();
    wait.WaitOne();
0 голосов
/ 13 апреля 2010

Использование отдельной работы по вызову собственного кода не решит проблему. Process API - это всего лишь тонкая оболочка для нативных функций процесса - их непосредственное использование просто сделает ваш код более запутанным и вызовет другие проблемы.

Похоже, проблема, в данном случае, это ваш "myapp.exe". По какой-то причине это приложение не заканчивается на этих машинах. Если вы обнаружите, что является причиной этого, вы, вероятно, сможете сделать это правильно, используя Process.Start.

...