2009-12-17 5 views
3

저는 많은 하위 프로세스를 시작할 C# 프로그램을 작성하고 있습니다. 나중에 ID로 해당 프로세스를 검색 한 다음 해당 프로세스를 처음 만들 때 사전에 추가 된 사전에 저장된 프로세스 집합과 일치시켜야합니다. 그러나, 나는.NET Frustration - Process.GetProcessById가 새 참조를 반환합니다.

Process notepad = new Process(); 
notepad.StartInfo.FileName = "notepad"; 
notepad.Start(); 

Process n2 = Process.GetProcessById(notepad.Id); 

Debug.WriteLine(notepad == n2);  //'False', but Why isn't this true??? 
Debug.WriteLine(notepad.Id == n2.Id); //'True' 

... 순수 우스꽝 것 같아 문제로 실행 해요 나는 GetProcessById는 '새로운 프로세스 (...)를'반환 찾아 .NET 리플렉터를 사용했습니다,하지만 이미 실행중인 프로세스에 대한 참조를 찾아 대신 반환해야하는 것처럼 보입니다.

첫 번째 디버그 문을 가정 할 수는 본질적으로

MyCustomDataType 데이터 = 내 사전 [메모장]과 같은 호출입니다;

원래 삽입 한 데이터를 얻으려는 대신 기본 비교기가 참조 검사를 수행하기 때문에 KeyNotFoundException이 표시 될 수 있습니다. 이 문제를 해결하기 위해 사전에 두 개의 Process 개체가 동일한 ID를 갖고 있는지 확인하는 사용자 지정 IComparer를 추가하여 관련 데이터를 예상대로 가져올 수 있습니다. 그러나 이것은 실행되지 않는 프로세스에 프로세스 ID가 없으므로 Process.ID에 대한 내 사용자 지정 IComparer의 호출이 InvalidOperationException을 throw하는 경우가 있습니다. 그래서 한 가지 문제를 해결하기 위해 다른 문제를 수정했습니다.

  • 왜 다만 이미 실행중인 프로세스 인스턴스에 대한 참조를 반환 .NET하지 않습니다

    그래서, 나는이 개 질문이 됐을까?

  • 프로세스 ID를 사용하는 것이 프로세스 개체의 수명 동안 항상 유효한 것은 아니므로 내 사전에 저장된 프로세스와 일치 시키려면 어떻게해야합니까?

답변

2

실행중인 프로그램은 프로세스 관리 유형의 인스턴스가 아니라 운영 체제 프로세스입니다. Process 형식은 운영 체제 개념을 중심으로 관리되는 래퍼 개체의 한 유형입니다. P/Invoke 호출을 숨김으로써 대상 프로세스를 제어 할 수 있습니다. 운영 체제에서는 이러한 작업을 수행하는 Process 클래스의 특정 인스턴스가 필요하지 않으므로 GetProcessById은 새 인스턴스를 반환 할 수 있으며 모든 작업을 수행 할 수 있습니다.

ID는 프로세스 자체의 유효 기간 동안 유효합니다. 아마도 EnableRaisingEvents을 true로 설정하고 캐시에서 프로세스를 제거하는 Process.Exited 이벤트에 이벤트 처리기를 추가 할 수 있습니까?

2

.net이 경우 어떻게 하시겠습니까?

은 첫번째 실행

Process notepad = new Process(); 
notepad.StartInfo.FileName = "notepad"; 
notepad.Start(); 

당신이 메모장 인스턴스의 프로세스 ID를 알고 있다고 가정합니다. 2 실행에서
, 당신이 실행

2 이드의를 사용하여 해당 프로세스를 잡아 싶은

참조 비교는 응용 프로그램 내에서 수행 할 수 있습니다
Process n2 = Process.GetProcessById(notepadIdInputByUser); 

개체, 개체의 건설이 당신의 손에 제공 (운영 체제와 대비).

.net은 어떻게 첫 번째 실행 파일에서 두 번째 실행 파일로 프로세스의 인스턴스를 가져 옵니까?

편집 : Process이 클래스이지만 비교할 수는 없습니다.
회원 비교를 할 수있는 struct처럼 동작합니다.의

2) 제안 그렇지 생성 List<string>의 유지 트랙의 생성 Process에 대해 동일한의 어떤 '입니다

var a = new List<string>{"one", "two", "three"}; 
var b = new List<string>{"one", "two", "three"}; 

if(a == b) { Debug.WriteLine("awesome"); } // not going to happen 

아무것도 :

2

1) 첫 번째 질문은 유사하다 Process을 사전에 저장하고 대신 프로세스 ID와 Process 참조를 저장하는 다른 클래스를 만들고 Process이 참조하는 프로세스가 더 이상 실행되지 않는 경우 지능적으로 처리합니다.

5

정말 확실하지 당신이 GetProcessByID MSDN 문서 명확하게 진술하기 때문에, 반사판에 의존했던 이유 :

새로운 프로세스의 구성 요소를 작성하고, 사용자가 지정하는 기존 프로세스 자원과 동료를.

프레임 워크는 사용자가 가진 동일한 인스턴스를 사용자에게 반환 할 수 없습니다. 이를 수행하기 위해, 프레임 워크는 이전에 작성된 모든 프로세스 인스턴스에 대한 참조를 유지하고 프로세스 ID를 비교하여 이미 가지고있는 프로세스 인스턴스를 찾아야합니다. 이것이 메모리와 프레임 워크의 성능에 미칠 영향을 상상해 보도록하겠습니다.

게다가 Process 클래스는 OpenProcess Win32 API에서 반환 한 프로세스 핸들을 감싸는 래퍼입니다. 동일한 프로세스에 대해 여러 개의 핸들을 가질 수 있습니다. 입출력 방향 재 지정은 핸들 단위로 수행 할 수 있으므로 동일한 프로세스를 나타내는 두 개의 Process 인스턴스를 가질 수 있어야하며 그 중 하나는 출력 및 오류 스트림을 처리하고 나머지 하나는 입력 스트림

별도의 메모에서 Process 개체 자체를 사전의 키로 사용하고있는 것으로 보입니다. 그러나 Process 객체는 실제 프로세스의 ID를 나타내지 않으며 프로세스의 표현 일뿐입니다. 대신 프로세스의 ID를 나타내는 키를 사용해야합니다.

+0

안녕하세요 Franci. 당신의 명확한 설명에 대해 너무 고마워요. 대신 '프로세스의 신원을 나타내는 핵심 항목으로 사용 하시겠습니까?' 나는 ID 외에 어떤 내장 된 속성도 생각할 수 없다. 또한 Process가 실행 중인지 여부와 상관없이 Process 객체의 수명 동안 살 수있는 속성이 필요합니다. – Chad

+0

프로세스 ID는 프로세스의 ID를 나타냅니다. :-) 그래서, 당신의 키는 프로세스 ID 여야합니다. 물론, 당신은 분명히 그것과 연관된 Process 객체와 당신이 현재의 사전에 보관하고있는 추가 데이터를 유지하기를 원할 것입니다. 프로세스 개체를 사용하여 사전에 보관 한 데이터를 확장하고 ID로 키를 입력하거나 ID로 키가 입력 된 프로세스 개체를 유지하는 두 번째 사전을 추가 할 수 있습니다. –

+1

프로세스 ID (PID)는 프로세스의 ID를 잘 나타내지 않습니다. 프로세스가 종료되면 나중에 새로운 프로세스에 대해 동일한 PID를 자유롭게 재사용 할 수 있습니다. 프로세스 ID와 프로세스가 시작된 시간의 튜플 (pid 리사이클링 케이스를 처리하기 위해)은 훨씬 더 나은 정체성이다. –

0

ProcessId를 사전의 키로 사용하십시오.

필요할 때마다 GetProcessById를 사용하여 Process의 새 인스턴스를 만드는 것을 두려워하지 마십시오. 그것은 가벼운 객체이고 가비지 컬렉터는 당신을 위해 정리할 것입니다.

관련 문제