문제

핵심 문제는 다음과 같습니다. com interop 별도의 appDomain에서. com 물건은 어셈블리를 기본 도메인으로 다시로드하는 것 같습니다.

내가 알고 싶은 것은 :이 예상되는 행동입니까, 아니면이 COM 관련 어셈블리가 잘못된 AppDomain에로드되도록하는 일을하고 있습니까? 아래 상황에 대한 자세한 설명을 참조하십시오 ...

응용 프로그램은 3 개의 어셈블리로 구성됩니다 .- 메인 exe, 응용 프로그램의 진입 점. -Iplugin 스타일의 인터페이스 아이콘 트롤러 만 포함하는 common.dll - 컨트롤러 .dll, 아이콘 트롤러 및 마샬 비어 포버를 구현하는 컨트롤러 클래스가 포함되어 있습니다. 이 클래스는 모든 작업을 수행하고 COM Interop을 사용하여 다른 응용 프로그램과 상호 작용합니다.

메인 엑스의 관련 부분은 다음과 같습니다.

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

common.dll에는 다음 두 가지만 포함합니다.

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

그리고 Controller.dll에는이 클래스가 포함되어 있습니다 (COM Interop Stuff라고도합니다).

public class Controller: IController, MarshalByRefObject

Application을 처음 실행할 때 Assembly.getAssemblies ()는 appdomains와 controller.dll이 컨트롤러 도메인에만로드되는 것으로 예상대로 보이며, common.dll이 예상대로 보입니다. 그러나 C.Run ()을 호출 한 후 COM 인터 로프와 관련된 어셈블리가 기본 앱 도메인에로드되었으며 COM 인터 로프가 발생하는 앱 도메인이 아닌 것으로 나타났습니다.

왜 이런 일이 발생합니까?

관심이 있으시면 여기에 약간의 배경이 있습니다.

원래 이것은 1 appdomain 응용 프로그램이었습니다. 인터페이스하는 COM은 오랜 사용 기간 동안 안정적이지 않은 서버 API입니다. COM 작업에서 ComeXception (원인에 대한 유용한 진단 정보가없는)이 발생하면 COM 연결이 다시 작동하기 전에 전체 응용 프로그램이 다시 시작되어야합니다. COM 앱 서버에 다시 연결하면 즉시 COM 예외가 다시 발생합니다. 이것에 대처하기 위해 나는 com interop 물건을 별도의 appdomain으로 옮기려고 노력했다. 그래서 미스터리 comexceptions가 발생할 때, 그것이 일어나는 appdomain을 언로드하고, 새로운 것을 만들고, 다시 시작할 수있다. . 어쨌든 이론이었다 ...

도움이 되었습니까?

해결책

불행히도, COM 구성 요소는 앱 도메인의 맥락 내에가 아닌 프로세스 공간 내에로드됩니다. 따라서 기본 DLL (COM 및 P/Invoke에 모두 적용)을 수동으로 찢기 (릴리스 및 언로드)해야합니다. 단순히 AppDomain을 파괴하는 것은 좋지 않지만 COM 상태를 재설정하는 데 전체 프로세스를 다시 작성할 필요는 없습니다 (COM 개체를 재현하는 것도 일반적으로 작동해야합니다. 이것은 구성 요소 제공 업체 코드 내에서 버그처럼 들립니다. 그들은 그것을 해결할 수 있습니까?)

참조

(Technet) 공정 주소 공간

(MSDN) 응용 프로그램 도메인

(MSDN) 경계 : 프로세스 및 앱 도메인

다른 팁

Shaun Wilson의 답변이 맞다는 증거는 다음과 같습니다.

Com App Domain

컨트롤러 MBR을 만들지 마십시오. 두 번째 도메인에 컨트롤러를로드하고 시작하는 작은 프록시를 만듭니다. 이렇게하면 컨트롤러 DLL이 첫 번째 도메인에로드되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top