2010-08-17 3 views
5

우리의 응용 프로그램이 System.Diagnostics.Process을 통해 프로세스를 생성 배경 스레드를 가지고 응답 :프로세스 .NET에서 Process.Start를 통해 양산 스레드

Process.Start(
    new ProcessStartInfo 
    { 
     FileName = url, 
     UseShellExecute = true 
    } 
); 

이것은 전혀 문제가 없습니다하는 데 사용됩니다. 하지만 이제 배경 스레드가 자동으로 죽어 가고 있습니다. 전화에서 Process.Start으로 결코 돌아 오지 않습니다. System.Exception을 처리하는이 코드의 catch 블록에도 도달하지 못합니다. Visual Studio 디버거에서 throw 될 때 예외를 처리 할 수있게해도 예외가 없습니다. 이상하게도, 그 과정은 잘 산란 해지고 있습니다. 사용자의 기본 브라우저가 예상 URL과 함께 시작됩니다.

우리 프로세스의 진입 점은 권장대로 [STAThread]으로 표시됩니다.

우리 스레드가 자동 종료되도록 할 수있는 원인은 무엇입니까? 스레드 종료 중에 무슨 일이 일어나고 있는지 디버깅하는 데 사용할 수있는 기술이 있습니까?

업데이트 :

스레드가 결국 살아처럼 보이는; 그것은 단지 전화에서 돌아 오지 않을뿐입니다. 여기에 자사의 스택 추적입니다!!

  • [수면 대기에서 또는 가입]
  • System.dll을 System.Diagnostics.ShellExecuteHelper.ShellExecuteOnSTAThread() + 0x63 바이트
  • System.dll을 System.Diagnostics.Process가 .StartWithShellExecuteEx (System.Diagnostics.ProcessStartInfo startInfo) + 0x19d 바이트
  • System.dll을! System.Diagnostics.Process.Start() + 아님 0x39 바이트
  • System.dll을! System.Diagnostics.Process.Start (System.Diagnostics 네임 .ProcessStartInfo startInfo) + 0x32 바이트
  • ,210
  • 내 방법

업데이트 2 : 해결 방법으로 작업을 실행하기 위해 쉘을 사용하지 않고

런칭 cmd.exe를. 무리 감사! 그러나, 나는 아직도 을 알고 싶습니다. 왜 콜이 돌아 오지 않는지 알고 싶습니다.

업데이트 3 :

쉘 후크는 반환하지에 대한 호출의 원인이 될 수 있는지에 대한 논리적 설명 같은 소리 않습니다. 불량 모듈을 찾을 수는 없지만 쉘 실행을 통해 실행하려는 마지막 시도 후에 으로 반환했습니다.

어쨌든 사용자가 프로세스 확장을 방해하여 코드가 반환되지 않을 수있는 셸 확장을로드했을 수 있습니다. 에 대해서는에 대해 아무 것도 할 수 없으므로 올바른 대답은 cmd.exe 프로세스를 시작하는 해결 방법을 사용하는 것입니다.

답변

4

Hans Passant에서 언급했듯이 Process.Start 콜이 그 이유 일 수 있습니다. Process.StartUseShellExecutetrue으로 설정하면 Windows API 함수 ShellExecuteEx이 특정 환경에서 반환되지 않을 수도 있습니다.

당신이 당신의 코드에 추적 메시지를 추가하여 경우인지 확인할 수 있습니다

System.Diagnostics.Trace.WriteLine("About to start process."); 
Process.Start(
    new ProcessStartInfo 
    { 
     FileName = url, 
     UseShellExecute = true 
    } 
); 
System.Diagnostics.Trace.WriteLine("Process started."); 

당신이 TraceListener를 사용할 수 있습니다 추적 메시지를 듣고는, 비주얼 스튜디오의 출력 창을 확인하거나를 사용 DebugView와 같은 도구.

해결 방법으로 start 명령을 사용할 수 있습니다. 다음 코드는 숨겨진 쉘 윈도우를 시작하여 URL을 "시작"합니다.

Process.Start(
    new ProcessStartInfo() 
    { 
     FileName = "cmd.exe", 
     Arguments = "/c start http://www.google.com", 
     WindowStyle = ProcessWindowStyle.Hidden, 
     UseShellExecute = false 
    }); 
+0

'Trace.WriteLine' 추가로 놀라움이 없습니다; "프로세스가 시작되었습니다." 라인에 도달하지 못했습니다. – Jacob

+0

cmd.exe를 시작할 때 호출이 여전히 반환되지 않습니다. – Jacob

+0

Bah, UseShellExecute를 false로 설정하면됩니다. – Jacob

4

Nah 스레드는 조용히 종료하지 않고 시끄러운 kaboom 사운드를냅니다. 적어도 출력 창에 스레드 종료 알림이 표시됩니다. Process.Start() 메소드 블로킹은 설명이 없어도 다른 설명이 될 수 있습니다. 당신은 스 니펫이 너무 짧아 괜찮은 진단을 내놓을 수 없습니다. 아마 환경적인 것.


귀하의 스택 트레이스는 사실에 약간의 도우미 스레드에서() 차단 Thread.join를 수행 않습니다 ShellExecuteOnSTAThread()를하는 데 도움이됩니다. 이 스레드는 기본 ShellExecuteEx() API 함수를 호출하는 데 필요하며 STA 스레드에서만 호출 할 수 있습니다. 그것은 결함이 있지만 STA 스레드는 또한 메시지 루프를 펌프해야합니다. 이 작은 도우미는하지 않습니다.

이 문제로 인해 컴퓨터에서 여전히 문제가 발생하지만 ShellExecuteEx() 호출을 가로채는 시스템 추가 기능이 있습니다. 그리고 실제 STA 스레드를 실행합니다. Debug + Windows + Threads 창에서 도우미 스레드를 다시 찾을 수 있어야합니다. 그것은 스택에 "ShellExecuteFunction"을 포함해야합니다. 예를 들어 스턴트를 가져 오는 '시스템 애드온'의 종류는 바이러스 스캐너입니다. 프로젝트의 디버깅 탭에서 "관리되지 않는 디버깅 사용"을 선택한 후 디버그 + Windows + 모듈 창에서 해당 에이리언웨어를 다시 찾을 수 있어야합니다.

UseShellExecute = false를 사용하는 해결 방법은 여기서는 상당히 허용됩니다. 당신의 기계가보기에 다소 엉망이된다는 사실은 물론 아닙니다.

+0

Visual Studio에서 출력 창을 검사했는데'Process.Start'를 시작한 후에 아무 것도 출력되지 않았습니다. 나는 그 호출이 블로킹 가능성을 고려해 보았다. 그러나 크롬의 모든 인스턴스를 종료 한 후에도 호출은 결코 리턴되지 않았다. (UseShellExecute와 함께 호출이 차단되는 이유는 모른다.) – Jacob

+0

글쎄, 디버거를 사용하라. 호출 스택을보십시오. Microsoft 기호 서버가 구성된 관리되지 않는 디버거가 가장 좋을 것입니다. –

+0

큰 충고, @ 한스. 더 많은 정보를 찾았습니다. 내 질문에 대한 업데이트를 참조하십시오. – Jacob

관련 문제