C #: проблема с командами оболочки

Я пытаюсь заставить парсер PHP запускать страницу, а затем возвращать результаты на мой сервер, однако, когда я запускаю команду через свой код, она ничего не возвращает. Я знаю, что команда правильная, потому что, если я запускаю ее вручную с тем же путем, она отлично работает. Вот мой код:

var p = new Process { StartInfo = new ProcessStartInfo("C:\\xampp\\php\\php.exe", path) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true } }; var output = new StringWriter(); var error = new StringWriter(); p.OutputDataReceived += (sender, args) => output.WriteLine(args.Data); p.ErrorDataReceived += (sender, args) => error.WriteLine(args.Data); p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(); if (p.ExitCode != 0) { throw new Exception(string.Format( "PHP failed with the following output:{0}{1}", /* {0} */ Environment.NewLine, /* {1} */ error.GetStringBuilder().ToString())); } var res = output.GetStringBuilder().ToString(); Console.WriteLine(res); 

EDIT: с помощью этого текущего кода он генерирует исключение в коде без вывода.

Задайте путь WorkDirectory

 var p = new Process { StartInfo = new ProcessStartInfo("php", path) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = workingDir } }; 

Проблема в том, что вы читаете результат до завершения программы. Вам нужно дождаться выхода программы для обработки вывода. В противном случае вы будете обрабатывать вывод до завершения анализа. Добавьте следующую строку.

 p.Start(); p.WaitForExit(); // New line 

EDIT OP сказал, что у них все еще есть проблемы.

Попробуйте удалить часть CMD команды. Просто запустите команду PHP напрямую. Также может быть полезно разрешить создание окна для целей отладки, чтобы вы могли видеть любые ошибки, которые могут возникнуть в результате выполнения команды.

Самый надежный способ вызвать процесс и зафиксировать его вывод или ошибку, попробовал бы его следующим образом:

 var p = new Process { StartInfo = new ProcessStartInfo("php", path) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true } }; var output = new StringWriter(); var error = new StringWriter(); p.OutputDataReceived += (sender, args) => output.WriteLine(args.Data); p.ErrorDataReceived += (sender, args) => error.WriteLine(args.Data); p.Start(); p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(); if (p.ExitCode != 0) { throw new Exception(string.Format( "PHP failed with the following output:{0}{1}", /* {0} */ Environment.NewLine, /* {1} */ error.GetStringBuilder().ToString())); } var res = output.GetStringBuilder().ToString(); Console.WriteLine(res); 

ReadToEnd() просто считывает все содержимое потока, как они есть в тот момент времени. Учитывая, что вы вызываете это сразу после Start() , поток, вероятно, пуст. У вас есть пара вариантов

  • Вместо этого ReadLine() , но это будет читать только одну строку
  • p.WaitForExit() затем вызовите ReadToEnd() , но я не уверен, что это держит поток открытым. Если это так, то это ваш лучший вариант.

Вам нужно добавить p.WaitForExit (); после p.Start (); иначе выход не будет готов, когда вы попытаетесь его прочитать.

Есть ли причина, по которой вы запускаете php через cmd? Не можете ли вы просто выполнить его прямо?

По моему опыту, выполнение процессов через .NET – худший способ выполнить другой процесс. fork () под Unix удивительно намного лучше. У меня было так много проблем, что мой совет заключается в том, что вы НАСТОЯТЕЛЬНО рассматриваете процесс Process.BeginOutputReadLine () и отправляете асинхронный маршрут в своем чтении. ReadToEnd и ReadToLine могут зависать бесконечно, особенно если у вас есть длинный вывод для захвата.

Я бы добавил пример, но он довольно длинный.