2009-05-03 4 views
3

PHP 파서에서 페이지를 실행 한 다음 결과를 내 서버로 반환하려고합니다. 그러나 코드를 통해 명령을 실행할 때 아무 것도 반환하지 않습니다. 나는 같은 경로로 수동으로 실행하면 명령이 올바르다는 것을 안다. Heres는 내 코드 :C# : 셸 명령 실행 문제

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

당신이 자세히 설명하면 무엇 우리는 더 나은 해결책을 찾을 수있었습니다. –

+0

"아무것도 반환하지 않습니다"라고 말하면 프로세스가 실행 된 후 res가 비어 있거나 결코 다시 돌아 가지 않는다는 것을 의미합니까? –

+0

죄송합니다. 빈 문자열 –

답변

5

설정 WORKINGDIRECTORY 경로 어쩌면

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

"시스템이 지정된 파일을 찾을 수 없습니다"라는 메시지와 함께 p.Start()에 예외가 발생합니다. –

+0

오류에 대해 자세히 설명해 주시겠습니까? php.exe를 찾지 못하면 전체 경로를 시도하십시오. 예 : StartInfo = new ProcessStartInfo ("C : \\ xampp \\ php \\ php.exe", 경로) –

+0

감사! –

5

문제는 프로그램을 끝내기 전에 출력을 읽는 것입니다. 출력을 처리하려면 프로그램 종료를 기다려야합니다. 그렇지 않으면 구문 분석이 완료되기 전에 출력을 처리하게됩니다. 에 다음 줄을 추가합니다.

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

편집 영업 이익은 여전히 ​​문제가있다.

명령의 CMD 부분을 제거해보십시오. PHP 명령을 직접 실행하십시오. 또한 디버깅 목적으로 창을 생성하여 명령을 실행할 때 발생할 수있는 오류를 볼 수 있도록하는 것이 좋습니다.

+0

당신은 나를 잡았어 +1 : –

+0

hrm, 나는 이것을 시도했다. 그러나 나는 여전히 같은 문제를 가지고있다. –

+0

Hrm, 나는 cmd 부분을 제거하려고 시도했다. 그러나 그때 나에게 "파일 이름, 디렉토리 이름 또는 볼륨 레이블 구문이 올바르지 않습니다. " –

1

ReadToEnd()은 스트림의 전체 내용을 그 시점에서 그대로 읽습니다. Start() 바로 뒤에 이것을 호출하면 스트림이 비어있을 가능성이 큽니다. 당신은 옵션

  • 대신 전화 ReadLine()의 몇 가지있다, 그러나 이것은 단지 하나 개의 라인
  • p.WaitForExit() 다음 ReadToEnd() 전화를 읽을 수 있지만, 나는이 열려있는 스트림을 유지 특정 아닙니다. 이 경우, 이것이 최선의 선택입니다.
1

p.WaitForExit();을 추가해야합니다. p.Start(); 그렇지 않으면 출력을 읽을 때 준비가되지 않습니다.

0

PHP를 통해 PHP를 실행하는 이유가 있습니까? 그냥 직접 실행할 수 없습니까?

.NET을 통해 프로세스를 실행하는 것이 다른 프로세스를 실행하는 최악의 방법입니다. 유닉스에서 fork()가 놀랍도록 훨씬 낫다. 나는 많은 조언을했다는 조언을 드리며 STRONGLY을보고 Process.BeginOutputReadLine()을보고 비공식적 인 경로를 읽으십시오. ReadToEnd 및 ReadToLine은 특히 캡처 할 출력이 길면 무기한 정지 될 수 있습니다.

나는 예제를 붙이 겠지만 다소 길다.

+0

이 방법을 사용하고 싶습니다. 제 생각에는 MSDN의 예가 다소 좋지 않습니다. 예제를 게시 할 수 있습니까? –

+0

이 모든 것을 랩핑하기 위해 작성한 클래스가 작동 중입니다. 중간에 요점은 Process.OutputDataReceived를 문자열을 증가하는 개인 클래스 문자열에 연결하는 클래스 정적 메서드로 설정하는 클래스입니다. 프로세스 실행이 끝나면 public 속성을 통해 문자열에 액세스합니다. stderr에 대해 stdout과 동일한 작업을 수행 할 수 있습니다. 사실상 프로세스가 있어야합니다. :) –

+0

나는 그것을 시험해 보았지만 어느 쪽도 효과가 없었다. –

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

OK 나는 이것을 시험해 보았다. 나는 명령 부분을 편집해야했다. 그것을 "cmd", "/ c php"+ 경로로 변경했습니다. 그리고 나서 오류 출력으로 얻었습니다 : " ''php '가 내부 또는 외부 명령으로 인식되지 않습니다. 작동 가능한 프로그램 또는 배치 파일." 하지만 이것에 관한 이상한 점은 명령 프롬프트를 열고 실행하면 php 명령이 작동한다는 것입니다 ... –

+0

PHP 실행 파일의 전체 절대 경로를 ProcessStartupInfo 생성자의 첫 번째 인수로 지정해보십시오. "cmd"를 사용하는 것은 과도한 행동입니다. –

+0

좋아, 나는 이것을 시도하고 빈 출력 예외를 던졌다. –