다음을 통해 공유


In-Process 확장 구현 지침

In-Process 확장은 이를 트리거하는 모든 프로세스에 로드됩니다. 예를 들어 셸 네임스페이스 확장은 직접 또는 간접적으로 셸 네임스페이스에 액세스하는 모든 프로세스에 로드할 수 있습니다. 셸 네임스페이스는 일반적인 파일 대화 상자 표시, 관련 응용 프로그램을 통한 문서 시작 또는 파일을 나타내는 데 사용되는 아이콘 가져오기와 같은 많은 셸 작업에서 사용됩니다. In-Process 확장은 임의 프로세스에 로드될 수 있으므로 호스트 애플리케이션 또는 다른 In-Process 확장에 부정적인 영향을 주지 않도록 주의해야 합니다.

특히 주목할 만한 런타임 중 하나는 CLR(공용 언어 런타임)으로, 관리 코드 또는 .NET Framework으로도 알려져 있습니다. Microsoft는 Windows 탐색기 또는 인터넷 익스플로러에 관리 코드 기반의 In-Process 확장을 작성하는 것을 권장하지 않으며, 이는 지원되는 시나리오로 간주하지 않습니다.

이 항목에서는 CLR 이외의 런타임이 In-Process 확장에서 사용하기에 적합한지 여부를 결정할 때 고려해야 할 요인에 대해 설명합니다. 다른 런타임의 예로는 Java, Visual Basic, JavaScript/ECMAScript, Delphi 및 C/C++ 런타임 라이브러리가 있습니다. 또한 이 항목에서는 관리 코드가 In-process 확장에서 지원되지 않는 몇 가지 이유를 제공합니다.

버전 충돌

단일 프로세스 내에서 여러 런타임 버전의 로드를 지원하지 않는 런타임을 통해 버전 충돌이 발생할 수 있습니다. 버전 4.0 이전의 CLR 버전은 이 범주에 속합니다. 한 버전의 런타임을 로드할 때 동일한 런타임의 다른 버전 로드가 제외되는 경우 호스트 애플리케이션 또는 다른 In-Process 확장에서 충돌하는 버전을 사용하는 경우 충돌이 발생할 수 있습니다. 인프로세스 확장에서 다른 확장과 버전 충돌이 발생할 때, 충돌을 재현하기 어려울 수 있습니다. 이는 실패에 충돌을 일으키는 정확한 확장이 필요하며, 실패의 양상이 충돌하는 확장이 로드되는 순서에 따라 달라지기 때문입니다.

버전 4.0 이전의 CLR 버전을 사용하여 작성된 In-Process 확장을 고려합니다. 파일 열기 대화 상자를 사용하는 컴퓨터의 모든 애플리케이션은 잠재적으로 대화 상자의 관리 코드와 관련 CLR 종속성을 애플리케이션 프로세스에 로드할 수 있습니다. 먼저 4.0 이전 버전의 CLR을 애플리케이션 프로세스에 로드하는 애플리케이션 또는 확장은 해당 프로세스에서 나중에 사용할 수 있는 CLR 버전을 제한합니다. 열기 대화 상자가 있는 관리되는 애플리케이션이 충돌하는 버전의 CLR을 기반으로 하는 경우 확장이 제대로 실행되지 않고 애플리케이션에서 오류가 발생할 수 있습니다. 반대로, 확장이 프로세스에서 가장 먼저 로드되고 충돌하는 버전의 관리 코드가 실행하려고 하면(관리되는 애플리케이션 또는 실행 중인 애플리케이션이 요청 시 CLR을 로드할 수 있음) 작업이 실패합니다. 사용자에게 애플리케이션의 일부 기능이 임의로 작동을 중지하거나 애플리케이션이 신비하게 충돌하는 것처럼 보입니다.

CLR 버전이 버전 4.0 이상과 같거나 이후 버전이 서로 공존하고 CLR의 4.0 이전 버전과 공존하도록 설계되었기 때문에 일반적으로 버전 관리 문제에 취약하지 않습니다(다른 버전과 공존할 수 없는 버전 1.0 제외). 그러나 이 항목의 나머지 부분에서 설명한 대로 버전 충돌 이외의 문제가 발생할 수 있습니다.

성능 문제

성능 문제는 프로세스에 로드될 때 상당한 성능 저하를 초래하는 런타임에서 발생할 수 있습니다. 성능 저하는 메모리 사용량, CPU 사용량, 경과된 시간 또는 주소 공간 사용의 형태일 수 있습니다. CLR, JavaScript/ECMAScript 및 Java는 강력한 런타임으로 알려져 있습니다. In-Process 확장은 많은 프로세스에 로드될 수 있으며 성능에 민감한 순간(예: 사용자에게 표시할 메뉴를 준비할 때)에서 수행되는 경우가 많기 때문에 강력한 런타임은 전반적인 응답성에 부정적인 영향을 미칠 수 있습니다.

상당한 리소스를 사용하는 강력한 런타임은 호스트 프로세스 또는 다른 In-process 확장에서 오류를 일으킬 수 있습니다. 예를 들어 힙에 수백 메가바이트의 주소 공간을 사용하는 강력한 런타임으로 인해 호스트 애플리케이션이 큰 데이터 세트를 로드할 수 없게 될 수 있습니다. 또한 In-Process 확장을 여러 프로세스에 로드할 수 있으므로 단일 확장의 높은 리소스 소비는 전체 시스템에서 높은 리소스 사용량을 빠르게 곱할 수 있습니다.

런타임이 로드된 상태로 유지되거나 해당 런타임을 사용하는 확장이 언로드된 경우에도 리소스를 계속 사용하는 경우 해당 런타임은 확장에서 사용하기에 적합하지 않습니다.

.NET Framework와 관련된 문제

다음 섹션에서는 확장에 관리 코드를 사용할 때 발생하는 문제의 예에 대해 설명합니다. 발생할 수 있는 모든 가능한 문제의 전체 목록은 아닙니다. 여기서 설명하는 문제는 확장에서 관리 코드가 지원되지 않는 이유와 다른 런타임의 사용을 평가할 때 고려해야 할 사항입니다.

재진입성

예를 들어, Monitor.Enter, WaitHandle.WaitOne 또는 경합된 lock 문으로 인해 CLR이 STA(단일 스레드 아파트) 스레드를 차단하면, 표준 구성에서 CLR은 대기하는 동안 중첩된 메시지 루프에 진입합니다. 많은 확장 메서드는 메시지를 처리하는 것이 금지되어 있으며, 예측할 수 없고 예기치 않은 재진입으로 인해 비정상적인 동작이 발생하여 재현하고 진단하기 어려울 수 있습니다.

더 멀티스레드 아파트먼트

CLR은 COM(구성 요소 개체 모델) 개체를 위한 런타임 호출 가능 래퍼을 만듭니다. 이러한 동일한 런타임 호출 가능한 래퍼는 나중에 멀티스레드 아파트(MTA)의 일부인 CLR의 종료자에 의해 제거됩니다. STA에서 MTA로 프록시를 이동하려면 마샬링이 필요하지만 확장에서 사용되는 모든 인터페이스를 마샬링할 수 있는 것은 아닙니다.

비결정적 개체 수명

CLR에는 네이티브 코드보다 약한 개체 수명 보장이 있습니다. 많은 확장에는 개체 및 인터페이스에 대한 참조 개수 요구 사항이 있으며 CLR에서 사용하는 가비지 수집 모델은 이러한 요구 사항을 충족할 수 없습니다.

  • CLR 개체가 COM 개체에 대한 참조를 가져오는 경우 런타임 호출 가능 래퍼가 가비지 수집될 때까지 런타임 호출 가능 래퍼에서 보유한 COM 개체 참조가 해제되지 않습니다. 비결정적 릴리스 동작은 일부 인터페이스 계약과 충돌할 수 있습니다. 예를 들어, Load 메서드가 반환될 때 개체가 속성 모음에 대한 참조를 남기면 안 된다는 것이 IPersistPropertyBag::Load 메서드의 요구사항입니다.
  • CLR 개체 참조가 네이티브 코드로 반환되는 경우, 런타임 호출 가능 래퍼는 런타임 호출 가능 래퍼의 Release에 대한 최종 호출이 이루어질 때 CLR 개체에 대한 참조를 포기합니다. 그러나 근본적인 CLR 개체는 가비지 수집될 때까지 완전히 종료되지 않습니다. 비결정적 종료는 일부 인터페이스 계약과 충돌할 수 있습니다. 예를 들어 썸네일 처리기는 참조 수가 0으로 떨어질 때 모든 리소스를 즉시 해제해야 합니다.

관리 코드 및 기타 런타임의 허용 가능한 사용

관리 코드 및 기타 런타임을 사용하여 Out-of-process 확장을 구현하는 것이 허용됩니다. Out-of-process Shell 확장의 예는 다음과 같습니다.

  • 미리 보기 처리기
  • 명령줄 기반 작업은 \동사\명령 하위 키에 등록된 작업과 같습니다.
  • 셸 확장 지점에서 프로세스 외부에서의 활성화를 허용하는 경우, 로컬 서버에서 구현된 COM 개체입니다.

일부 확장은 in-process 또는 out-of-process 확장으로 구현될 수 있습니다. 프로세스 내 확장에 대한 이러한 요구 사항을 충족하지 않는 경우 이러한 확장을 Out-of-process 확장으로 구현할 수 있습니다. 다음 목록에서는 in-process 또는 out-of-process 확장으로 구현할 수 있는 확장의 예를 보여 줍니다.

  • IExecuteCommand\동사\명령 하위 키 아래에 등록된 DelegateExecute 항목과 연결되어 있습니다.
  • IDropTarget\동사\DropTarget 하위 키에 등록된 CLSID와 연결됩니다.
  • IExplorerCommandState은/는 CommandStateHandler 항목과 연결되어 있으며, \동사 하위 키에 등록되었습니다.