2012-06-01 1 views
7

파일을 여는 데 Process.Start (string Filename)를 사용하는 응용 프로그램이 있습니다. 이 메서드 오버로드로 인해 시스템은 파일 이름 확장명을 기반으로 적절한 응용 프로그램을 호출합니다. 제 경우에는 일반적으로 WORD, PPT, PDF, JPG 등입니다 ... 볼 수있는 문서의 일부 유형입니다. 궁극적으로 프로세스를 시작한 다음 나중에 응용 프로그램에서 MainWindowHandle 값을 사용하여 작업해야합니다.System.Diagnostics.Process.Start() 이상한 동작

나는 두 가지를 개방하고있어, 다른 방법을 반환 Process.Start를 (문자열 파일 이름) 의 원인이 적어도 세 가지의 경우 ... 아래의 제 1 및 제 2 경우에

가정을 발견했습니다. AcroRd32가 실행되지 않고, 내가 좋아하는 뭔가를 할 경우 : PDF 파일 ...

사례 1 (그러나 같은 일이 내가 두을 .ppt 또는 두 개의 .doc 파일뿐만 등을 여는 경우 일이 나타납니다).

Process p = Process.Start("yada.pdf"); 
p.WaitForInputIdle(); 
p.Refresh(); 

예상대로 작동합니다. p.MainWindowHandle 값이 올바르게 채워집니다. 이 경우 문제가 없습니다.

사례 2 : 이제 Process.Start()를 호출 할 때를 가정합니다. AcroRd32는 이미 열려있는 pdf 파일에서 실행중인 입니다. 이제 상황이 이상해진다. 을 참조하면, 을 Process.Start()로 호출 한 후 p.MainWindowHandle의 값이 0이고 ( 창이 생성 되었음에도 불구하고), p.MainWindowTitle이 다음과 같은 코드 (명확성을 위해 일부 오류 검사 로직이 제거됨)를 참조하십시오. 빈. 그런 다음 1 초 잠을 핸들은 여전히 ​​제로이지만, mainwindowtitle 지금 (인구도 나는 잠 후 p.Referesh()를 호출하지 않았지만. < < < < "이 추적 문 의 각을 "코멘트에 런타임에 인쇄되어 있습니다.

Process p = Process.Start("SomeFileName.pdf"); 
p.WaitForInputIdle(); 
p.Refresh(); 
if (p.MainWindowHandle == 0) 
    DebugTrace("MainWindowHandle is zero, why??"); //<<<< 
if (p.MainWindowTitle.Length == 0) 
    DebugTrace("MainWindowTitle is null");   //<<<< 
Thread.Sleep(1000); 
if (p.MainWindowHandle == 0) 
    DebugTrace("MainWindowHandle is still zero."); //<<<< 
if (p.MainWindowTitle.Length == 0) 
    DebugTrace("MainWindowTitle is null"); 
else 
    DebugTrace("MainWindowTitle: " + p.MainWindowTitle); //<<<< 

나는이 AcroRd32이 실행이 이미 사실 함께 할 수있는 뭔가가 확신 해요,하지만 난 그 여부를 제어 할 수 없습니다 내가 값을 얻을 필요합니까 p.MainWindowHandle의 .이 문제를 해결하는 방법은 무엇입니까?

사례 3 : 그런 다음 세 번째 경우에 : 경우에 따라 Process.Start()는 파일을 성공적으로 열었을 때도 null 을 반환합니다. 이게 .jpg 파일의 경우 인 것으로 확인되었지만 .jpg 확장자에 할당 된 응용 프로그램에 따라 달라집니다. Process.Start ("file.jpg")는 응용 프로그램이 "Windows Photo Viewer"인 경우 null 을 반환하지만 "Paint"로 변경하면 null을 반환하지 않습니다. 그게 뭐야? 그리고 어떻게하면 핸들을 얻을 수 있습니까?

모두 완료되었습니다. 세부 사항에 대해 유감스럽게 생각하지만, 상황을 설명하고 있습니다. 작업을 완료하려고합니다!

+1

호기심에서 벗어나서 MainWindowHandle과 어떤 관계가 있습니까? 아마 더 좋은 방법이있을 것입니다! – banging

+0

윈도우의 위치/크기를 추적해야하며 현재 윈도우 핸들을 입력으로 사용하는 GetWindowRect()를 사용하고 있습니다. Process.Start()의 제약으로 인해 활성 윈도우가 파일 이름을 알고있을 때와 프로세스 이름을 알고있을 때 무엇을 기반으로하는지 추측해야합니다. 이상적으로는 추측 할 필요가 없습니다! :-) –

답변

2

acroRd32로 창을 시작한 다음 acroRd32가 주어진 파일 경로를 따라 실행중인 인스턴스로 전달한 다음 종료합니다.

이것은 일반적으로 프로그램의 여러 인스턴스를 피하는 방법입니다 ...

+0

Understood, 나는 powerpoint, word 등에서 같은 일이 일어난다는 것을 확신합니다. 문제는이 코드로 이러한 경우 사용할 수없는 것으로 보이는 창 핸들을 가져와야한다는 것입니다. –

+0

GetProcesses를 사용하여 AcroRd32가 있는지 확인하고 거기에서 메인 핸들을 검색하십시오. http://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle.aspx – Schwarzie2478

+0

어떤 과정이 시작될 지 알지 못한다. 위의 예제에서 acroRd32를 사용했지만 워드 문서, 파워 포인트, jpeg가 될 수 있습니다. 어떤 응용 프로그램이든 파일 확장자에 연결됩니다. 위에서 분명하지 않은 한 가지 사실은 Process.Start()에 전달 된 문자열이 임의적이라는 사실입니다. –

0

Process.Start가 반환하는 MainWindowHandle에 의존 할 수 없습니다. 언급 한 바와 같이, 파일이 완전히 실행중인 응용 프로그램에 의해 열리면 반환하지 않습니다. Windows Vista 이후 MS는 ReStart Manager를 추가했습니다. ReStart Manager는 주어진 파일에서 잠금 프로세스를 제공 할 수있는 새로운 API입니다. https://msdn.microsoft.com/en-us/magazine/cc163450.aspx

내 문제는 Process.Start의 MainWindowHandle과 잠금 핸들 ReStart 관리자가 반환하는 것이 었습니다. MSDN 매거진의 예제 코드가 있습니다. https://github.com/andrewchaa/PopOpen/blob/master/Pop.Cs/InUseDetection.cs