C#:运行shell命令时出现问题

我正在尝试让PHP解析器运行一个页面,然后将结果返回给我的服务器,但是当我通过我的代码运行命令时,它什么都不返回。 我知道命令是正确的,因为如果我用相同的路径手动运行它,它工作正常。 inheritance我的代码:

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); 

编辑:使用此当前代码,它会在没有输出的代码中抛出exception。

设置WorkingDirectory路径

 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()之后; 否则,当您尝试读取输出时,输出尚未就绪。

你有没有理由通过cmd运行php? 你不能直接执行它吗?

根据我的经验,通过.NET执行进程是执行另一个进程的最糟糕方式。 unix下的fork()非常好。 我有很多问题,我的建议是你强烈考虑查看Process.BeginOutputReadLine()并在你的阅读中走异步路径。 ReadToEnd和ReadToLine可以无限期挂起,尤其是如果要捕获冗长的输出。

我会粘贴一个例子,但它相当冗长。