2009-05-03 119 views
3

我试图让PHP解析器运行一个页面,然后将结果返回给我的服务器,但是当我通过我的代码运行命令时,它不返回任何内容。我知道该命令是正确的,因为如果我用相同的路径手动运行它,它工作正常。我的继承人代码:C#:运行shell命令的问题

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

编辑: 有了这个当前的代码,它抛出在没有输出的代码除外。

+0

也许如果您详细解释一下你正在努力去做,我们可以找到更好的解决方案。 – 2009-05-03 14:27:17

+0

当你说“它什么都没有返回”时,你是说res在进程运行后是空的,还是永远不会退步? – 2009-05-03 19:33:47

+0

对不起,返回空字符串 – 2009-05-03 19:52:32

回答

5

设置WorkingDirectory路径

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

问题是您在程序结束前正在读取输出。您需要等待程序退出来处理输出。否则,您将在解析完成之前处理输出。添加以下行。

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

编辑 OP说,他们仍然有问题。

尝试删除命令的CMD部分。只需直接运行PHP命令。允许创建一个用于调试目的的窗口也许是有益的,因此您可以看到运行该命令可能出现的任何错误。

+0

你有我,+1 :) – 2009-05-03 14:27:15

1

ReadToEnd()只是读取流在当时的整个内容。鉴于您在Start()之后立即打电话,该流可能为空。你有几个选项

  • 呼叫ReadLine()代替,但这只会读取一行
  • p.WaitForExit()然后调用ReadToEnd(),但我不能肯定这保持流开放。如果是这样,那么这是你最好的选择。
1

您需要添加p.WaitForExit();在p.Start()之后;否则当您尝试读取输出时,输出未准备好。

0

是否有你通过cmd运行php的原因?你不能直接执行它吗?

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

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

2

最稳健的方式来调用过程并捕获它的输出或错误会尝试一下以下的方法:

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