Sunday 4 February 2018

C # 시스템 진단 프로세스 시작 waitforexit


C # system. diagnostics. process. start waitforexit
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
System. Diagnostics. Process WaitForExit은 시간 초과시 프로세스를 종료하지 않습니다.
내 C # 코드에서 7-zip을 실행합니다.
이제 내가보기에 타임 아웃이 발생하면 작업 관리자에 여전히 7-zip 프로세스가 존재합니다. 왜 그런 일이 일어나는거야? 나는 둘 다 닫고 처분한다.
귀하의 질문에 프로세스 클래스에 대한 세 가지 방법을 언급 :
그 방법들 중 아무 것도 과정에 아무 것도하지 않을 것이며, 확실히 그것을 죽이지는 않을 것입니다.
WaitForExit은 관측 방법이며, 프로세스가 자체적으로 종료되는지를 기다립니다. 시간 초과로 인한 과부하는 메소드가 프로세스가 종료되었는지 여부를 관찰 할 수 있는지 알려주는 bool을 반환합니다. 그렇지 않은 경우 아마도 아직 실행 중일 것입니다.
Close 및 Dispose는 실행중인 프로세스에 대해 또는 프로세스에 대해 아무 작업도 수행하지 않고 프로세스 클래스에서 내부적으로 처리하는 핸들을 닫습니다. 이 핸들은 해당 클래스가 문제의 프로세스 탭을 유지할 수있는 메커니즘입니다.
실행중인 프로세스를 관찰 한 후에이 핸들을 닫는 것이 좋습니다.

C # system. diagnostics. process. start waitforexit
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
c # ProcessStartInfo. Start - 출력을 읽지 만 시간 초과가 있습니다.
다른 프로세스를 시작하고 끝내기 위해 대기 (제한 시간이 있음)하려면 MSDN에서 다음을 사용할 수 있습니다.
다른 프로세스를 시작하고 출력을 읽으려면 다음 패턴을 사용할 수 있습니다 (SO에서)
어떻게 두 가지를 결합하여 모든 입력을 읽고 교착 상태에 빠지지 않고 실행중인 프로세스가 잘못되면 시간 초과가 발생합니까?
이 기술은 출력 버퍼가 4KB 이상의 데이터로 채워지는 경우 중지됩니다. 더 확실한 방법은 출력 스트림에 무언가가 기록 될 때 알림을받을 대리자를 등록하는 것입니다. 다른 게시물에서 이미이 방법을 제안했습니다.
두 클래스를 결합 할 필요는 없습니다. Process 클래스는 출력이 StandardOutput - OutputDataReceived로 보내질 때 발생하는 이벤트를 가지고 있습니다.
이벤트에 가입하면 도착한대로 출력물을 읽을 수있게되며, 메인 프로그램 루프에서 시간 초과를 할 수 있습니다.
첫 번째 메소드를 이와 같이 수정할 수 있습니다.
다음과 같이 APM을 사용할 수도 있습니다.
ReadToEnd 호출에 대한 대리자를 정의합니다.
그런 다음 대리인을 사용하여 다음과 같은 메서드를 호출합니다.
편집 : 오류 처리가 명확하게 제거되었습니다.
WaitForExit () 호출 아래 첫 번째 예제의 모든 것을 두 번째 예제에 추가하기 만하면됩니다.

C # system. diagnostics. process. start waitforexit
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
Process. Start는 프로세스가 시작될 때까지 대기합니다.
방법으로 계속 진행하기 전에 프로세스가 실행되고 있는지 확인해야합니다.
성명서는 :
WAIT 명령을 사용하거나이 값에 대한 지연을 설정할 수 있습니까?
완료 될 때까지 기다려야합니까? 그런 다음 Process. WaitForExit를 사용하십시오.
또는 메시지 루프에 들어가기를 기다리는 UI가있는 응용 프로그램이라면 다음과 같이 말할 수 있습니다.
마지막으로, 이들 중 어느 것도 적용되지 않는 경우 적절한 시간 동안 Thread. Sleep 만 적용하면됩니다.
나는 또한 이것을 한 번 필요로했고 나는 그 과정의 창 제목을 확인했다. 예상 한 응용 프로그램 인 경우 응용 프로그램이 실행 중인지 확인할 수 있습니다. 내가 확인한 응용 프로그램은 시작을위한 시간이 필요했고이 방법은 나에게 잘 맞았습니다.
다른 사람들이 이미 말했듯이, 당신이 묻는 것은 즉시 명백하지 않습니다. 프로세스를 시작한 다음 프로세스가 준비되면 다른 작업을 수행한다고 가정합니다.
물론, "준비가되어있다"는 까다로운 점입니다. 필요한 것에 따라 단순히 대기만으로 충분할 수 있습니다. 그러나보다 강력한 솔루션이 필요한 경우 명명 된 뮤텍스를 사용하여 두 프로세스 간의 제어 흐름을 제어 할 수 있습니다.
예를 들어, 주 프로세스에서 이름 지정된 뮤텍스를 작성하고 대기 할 스레드 또는 태스크를 시작할 수 있습니다. 그런 다음 두 번째 프로세스를 시작할 수 있습니다. 그 프로세스가 "준비가되었다"고 결정할 때, 네임드 뮤텍스 (물론 같은 이름을 사용해야 함)를 열고 첫 번째 프로세스에 신호를 보낼 수 있습니다.
'ChrisG'의 대답은 정확하지만 매번 MainWindowTitle을 새로 고쳐야하며 비어 있는지 확인하는 것이 좋습니다. 이렇게 :
나는 Tom과 동의한다. 또한 Thread. Sleep을 수행하는 동안 프로세스를 확인하려면 실행중인 프로세스를 확인하십시오. 같은 것 :
무엇보다도 : 나는 이것이 다소 오래되었다는 것을 알고 있습니다. 그러나 여전히 받아 들여지는 대답이 없기 때문에 아마 나의 접근법이 다른 누군가에게 도움이 될 것입니다. :)
내가 이것을 해결하기 위해 한 것은 :
연결 var time = process. StartTime은 프로세스가 시작되지 않는 한 예외를 throw합니다. 한 번 통과하면 프로세스가 실행 중이라고 추측하고 그 프로세스를 계속 사용하는 것이 안전합니다. 자바 프로세스가 시작될 때까지 기다리는 데는 시간이 걸리기 때문에 이것을 사용하고 있습니다. 이 방법은 Thread. Sleep ()을 사용하는 대신 응용 프로그램이 실행중인 컴퓨터에서 독립적이어야합니다.
나는 이것이 매우 깨끗한 해결책이 아니라는 것을 이해하지만, 성능에 독립적이어야한다고 생각할 수있는 유일한 것입니다.
자식 프로세스가 시작되기 전에 Start 메서드가 반환되는지 확실합니까? Start는 Start가 자식 프로세스를 동 기적으로 시작한다는 인상하에 항상 사용되었습니다.
자식 프로세스가 어떤 종류의 초기화를 마칠 때까지 기다리고 싶으면 프로세스 간 통신이 필요합니다 - C # (2.0)의 Windows 프로세스 간 통신을 참조하십시오.
ChrisG의 아이디어를 조금이라도 확장하려면 process. MainWindowHandle을 사용하고 창 메시지 루프가 응답하는지 확인하십시오. p를 사용하거나이 Win32 API 호출 : SendMessageTimeout. 그 링크에서 :
함수가 성공하면 반환 값은 0이 아닙니다. HWND_BROADCAST가 사용될 경우 SendMessageTimeout은 개별 창에 대한 정보를 제공하지 않습니다.
함수가 실패하거나 시간이 초과되면 반환 값은 0입니다. 확장 된 오류 정보를 얻으려면 GetLastError를 호출하십시오. GetLastError가 ERROR_TIMEOUT을 반환하면 함수가 시간 초과됩니다.
OP가 언급 한 것은 자식 프로세스에서 유효한 창 핸들을 가지고 있어야하므로 어떤 방식 으로든 처리 할 수 ​​있다는 것입니다.

사용 예제.
나는이 방법으로 그것을 해결했다.
나는 입력, 출력 및 오류 모두를 리디렉션하고 출력 및 오류 스트림에서 읽기를 처리했습니다. 이 솔루션은 Windows 7과 Windows 8 모두 SDK 7 - 8.1에서 작동합니다.
Mark Beers, Rob, stevejay 대답을 고려하여 비동기 스트림 읽기를 사용하여 문제를 해결할 클래스를 만들려고했습니다. 그렇게하면 비동기 프로세스 출력 스트림 읽기와 관련된 버그가 있음을 알았습니다.
당신은 그렇게 할 수 없습니다 :
System. InvalidOperationException이 발생합니다 : StandardOut가 리디렉션되지 않았거나 프로세스가 아직 시작되지 않았습니다.
그런 다음 프로세스가 시작된 후 비동기 출력 읽기를 시작해야합니다.
이렇게하면 출력 스트림이 비동기로 설정되기 전에 데이터를받을 수 있기 때문에 경쟁 조건을 만듭니다.
그렇다면 어떤 사람들은 스트림을 비동기로 설정하기 전에 스트림을 읽어야한다고 말할 수 있습니다. 그러나 같은 문제가 발생합니다. 동기 읽기 사이에 경쟁 조건이 있으며 스트림을 비동기 모드로 설정합니다.
"Process"와 "ProcessStartInfo"가 설계된 실제 방식으로 프로세스의 출력 스트림을 안전하게 비동기 적으로 읽는 방법은 없습니다.
다른 사용자가 제안한 것과 같이 비동기 읽기를 사용하는 것이 좋습니다. 그러나 경쟁 조건으로 인해 정보가 누락 될 수 있음을 알고 있어야합니다.
위의 답변 중 하나도 해당 작업을 수행하지 않습니다.
롭 솔루션이 중단되고 'Mark Byers'솔루션이 폐기 된 예외를 얻습니다. (다른 답변의 '솔루션'을 시도했습니다.)
그래서 나는 또 다른 해결책을 제안하기로 결정했다.
이 코드는 디버깅되어 완벽하게 작동합니다.
이것이 간단하고 더 나은 접근 방법입니다 (우리는 AutoResetEvent가 필요 없습니다) :
나는 같은 문제가 있었지만 그 이유는 다르다. 그러나 Windows 8에서는 발생하지만 Windows 7에서는 발생하지 않습니다. 다음 줄이 문제를 일으킨 것으로 보입니다.
해결책은 UseShellExecute를 비활성화하지 않는 것입니다. 원하지 않는 쉘 팝업 창을 받았지만 특별한 일이 일어나지 않을 때까지 기다리는 프로그램보다 훨씬 낫습니다. 그래서 다음과 같은 해결 방법을 추가했습니다.
이제 나를 귀찮게하는 것은 Windows 8에서 왜 이런 일이 일어나고 있는지입니다.
소개.
현재 허용되는 응답이 작동하지 않고 (예외가 throw 됨) 해결 방법이 너무 많지만 완전한 코드가 없습니다. 이것이 대중적인 질문이기 때문에 많은 사람들의 시간을 낭비하는 것은 분명합니다.
Mark Byers의 대답과 Karol Tyl의 대답을 결합하여 Process. Start 메서드를 사용하는 방법을 기반으로 전체 코드를 작성했습니다.
git 명령을 통해 진행 대화 상자를 만드는 데 사용했습니다. 이것이 내가 그것을 사용한 방법입니다 :
이론적으로 stdout과 stderr를 결합 할 수도 있지만 테스트하지는 않았습니다.
나는 이것이 늙다는 것을 알고 있지만이 전체 페이지를 읽은 후에는 해결할 수있는 코드가 없기 때문에 무하마드 레 한 (Muhammad Rehan)을 시도하지는 않았다. . 그것이 완전히 진실하지 않은 경우 작동하지 않는다고 말할 때, 때로는 잘 작동 할 것입니다. EOF 마크 전에 출력의 길이와 관련이 있다고 생각합니다.
어쨌든, 나를 위해 일한 솔루션은 다른 스레드를 사용하여 StandardOutput 및 StandardError를 읽고 메시지를 작성하는 것이 었습니다.
희망이 사람이 도움이되기를 바랍니다, 누가 힘들 수 있다고 생각!
내부 타임 아웃과 생성 된 애플리케이션에 의한 StandardOutput 및 StandardError의 사용으로 인해 다른 솔루션 (EM0를 포함하여)은 여전히 ​​내 애플리케이션에 대해 교착 상태입니다. 여기 나를 위해 일한 것입니다 :
편집 : StartInfo의 초기화를 코드 샘플에 추가했습니다.
이 게시물 어쩌면 구식하지만 난 왜 그것이 일반적으로 끊어지는 주된 원인은 redirectStandardoutput에 대한 스택 오버 플로우 때문이거나 redirectStandarderror가있는 경우입니다.
출력 데이터 또는 오류 데이터가 크기 때문에 무한정 지속되는 동안 정지 시간이 발생합니다.

No comments:

Post a Comment