2008-11-03 5 views
1

COM 개체의 인스턴스를 만들려고합니다. 인터페이스를 구현하는 클래스 이름이 있고 CLSIDFromProgID()를 사용하여 CLSID를 가져옵니다. 그래서 나는 CLSID를 얻고 있기 때문에 지금부터 모든 것이 잘되어야한다고 생각했습니다. 그러나 CreateInstance에 대한 호출을하고 CLSID를 전달할 때 "클래스가 등록되지 않았습니다."라는 오류가 발생합니다. 또한 일부 컴퓨터에서만이 오류가 발생합니다. 그것은 여러 컴퓨터에서 오류가 무료로 실행됩니다. 문제가 어디 있는지 이해할 수 없습니다. 내 레지스트리가 더럽습니까? 아무도 여기서 무슨 일이 일어나는 지 알아? 당신의 도움을 주셔서 감사합니다!CLSIDFromProgID는 성공했지만 CreateInstace는 실패합니다! 왜?

그냥 .NET COM 클래스라고 추가하고 싶습니다. 적절한 항목은 레지스트리에 있고 DLL은 GAC에 있습니다.

답변

1

답장을 보내 주셔서 감사합니다. .Net 어셈블리는 제대로 등록되었으며 GAC에있었습니다. 절대적으로 이것을 확인한 한 응용 프로그램은 Process Explorer였습니다. 각 응용 프로그램에서로드 한 dll을 볼 수 있습니다. 그래서 여기에서 COM 개체를 인스턴스화하는 응용 프로그램이 실제로 DLL을로드 할 수 있는지 여부를 확인할 수있었습니다. 나는 이것이 실제로 일어난다는 것을 알았다. 문제는 다른 지역 설정 때문이었습니다. 지역이 미국으로 설정되지 않은 경우 응용 프로그램에서 예외가 발생했습니다. 이 문제는 수정되었습니다. "등록되지 않은 클래스"라는 오류 메시지는별로 도움이되지 않았습니다. Thankfully 히 그것은 빠른 수정이었다.

+2

"별로 도움이되지 않습니다."실제로 COM의 작업 이름이었습니다. – bzlm

1

레지스트리에서 두 단계 프로세스입니다. ProgID를 사용하여 CLSID를 가져 왔습니다. 그런 다음 CreateInstance를 호출하면 COM은 CLSID를 사용하여 DLL에 대한 경로를 찾습니다. regedit를 사용하여 CLSID를 조회하고 해당 항목이 어떻게 보이는지 확인할 수 있습니다.

+0

. NET COM 클래스라고합니다. 그렇다면 CreateInstance()를 호출하면 어디에서 보입니까? – Juba

+1

나는 차이가 없다고 생각한다. COM은 COM입니다. 레지스트리는 CLSID를 dll에 대한 경로에 매핑합니다. –

1

CLSIDFromProgId는 단순히 레지스트리에서 ProgId의 이름을 찾아서 CLSID로 변환하기 만하면 레지스트리를 벗어나는 내용을 보거나 실제로 해당 CLSID를 구현하는지 확인할 필요가 없습니다.

CLSID에서 CreateInstance를 호출하면 Windows는 레지스트리에서 개체를 인스턴스화하는 방법 (일반적으로 exe 또는 dll)을 찾습니다. 그런 다음 dll을로드 (또는 exe를 시작)하고 객체를 만듭니다.

"COM Class Objects and CLSIDs"과 같은 많은 프로세스가 MSDN에 포함되어 있습니다. 많은 COM 작업을 수행하면 많은 시간을 절약 할 수 있으므로 첫 번째 보안 주체로부터 프로세스를 배우는 것이 좋습니다. 이 유형의 문제를 디버깅 할 때 번거 롭습니다.

+0

. NET COM 클래스라고합니다. 그렇다면 CreateInstance()를 호출하면 어디에서 보입니까? – Juba

+0

HKEY_CLASSES_ROOT \ CLSID \ {.. your clsid ..} \ 아래에서 찾으십시오. Server32 또는 InprocServer23 하위 키가 표시되어 개체를 처리하도록 실행 파일이 등록되어 있음을 알려줍니다. oleview 도구는 이러한 문제를 진단하는 데 유용합니다 ...Visual Studio 명령 프롬프트를 열고 다음을 입력하십시오. oleview –

0

예를 들어 shell32를 사용하면 다음과 같이 새 인스턴스를 만들 수 있습니다.

var shl = (Shell) Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application")); 

이것은 기존 구성 요소에 대한 참조입니다.

var shl2 = (Shell) Marshal.GetActiveObject("Shell.Application"); 

다음은 IronPython에서 동일한 작업을 수행하는 방법에 대한 참조입니다.

** 참고,이 CLSID 그냥 Type.GetTypeFromCLSID ({GUID}를) 사용, 거의 동일한 것, ProgID를 사용했다.

관련 문제