3

I'm trying to get the PHP parser to run a page and then return the results to my server, however when I run the command via my code, it returns nothing. I know the command is correct because if I run it manually with the same path, it works fine. Heres my code:

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: With this current code, it throws the exception in the code with no output.

4
  • Maybe if you explain in detail what you're trying to do, we could find better solutions. Commented May 3, 2009 at 14:27
  • When you say, “it returns nothing,” do you means res is empty after the process runs or that it never retutrns? Commented May 3, 2009 at 19:33
  • Sorry, returns an empty string Commented May 3, 2009 at 19:52
  • Have you tried reading standard error? Maybe there is some output sitting in there? Commented May 4, 2009 at 9:31

6 Answers 6

5
+150

Set WorkingDirectory Path

var p = new Process
            {
                StartInfo = new ProcessStartInfo("php", path)
                {
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    WorkingDirectory = workingDir
                }
            };
Sign up to request clarification or add additional context in comments.

2 Comments

Throws an exception on p.Start() with this message: "The system cannot find the file specified"
can you elaborate on the error that you got? if it cant find the php.exe then try full path eg:StartInfo = new ProcessStartInfo("C:\\xampp\\php\\php.exe", path)
5

The problem is that you are reading the output before the program finishes. You need to wait for program exit to process the output. Otherwise you'll be processing the output before the parse is complete. Add the following line in.

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

EDIT OP said they are still having problems.

Try removing the CMD portion of the command. Just run the PHP command directly. It also may be beneficial to allow the creation of a window for debugging purposes so you can see any errors that may come out of running the command.

1 Comment

Hrm, I tried removing the cmd part, but then it gives me an exception that says "The filename, directory name, or volume label syntax is incorrect"
2

The most robust way to invoke the process and capture its output or error would to try it the following way:

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

3 Comments

OK i tried this, I had to edit the command part. changed it to "cmd", "/c php " + path. and then i got this as the error output: "'php' is not recognized as an internal or external command, operable program or batch file." But the weird thing about this is that the php command works if i open up the command prompt and run it...
Try specifying the full, absolute, path to the php executable as the first argument to the ProcessStartupInfo constructor. Using "cmd" is an overkill.
Ok, I tried this and it threw the exception with blank output.
1

ReadToEnd() just reads the entire contents of the stream as they are at that point in time. Given that you're calling this immediately after Start(), the stream is likely empty. You have a couple of options

  • Call ReadLine() instead, but this will only read one line
  • p.WaitForExit() then call ReadToEnd(), but I am not certain this keeps the stream open. If this does, then this is your best option.

Comments

1

You need to add p.WaitForExit(); after the p.Start(); else the output is not ready when you try to read it.

Comments

0

Is there a reason you're running php through cmd? Can't you just execute it directly?

It has been my experience that executing processes through .NET is the worst way to execute another process. fork() under unix is amazingly much better. I have had so many issues that my advice is that you STRONGLY consider looking at Process.BeginOutputReadLine() and go the asynchronous route in your reading. ReadToEnd and ReadToLine can hang indefinitely especially if you have lengthy output to capture.

I would paste an example but it is rather lengthy.

2 Comments

I would like to try this, but in my opinion, the example on MSDN is rather poor, could you please post your example?
The class I wrote to wrap all this is at work. In the interim, the gist is a class that sets Process.OutputDataReceived to a class static method that concats the string to a growing private class string. When done executing the process you access the string via a public property. You can do the same thing for stderr as stdout. Effectively, it's what Process should be. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.