2008-11-03 5 views
1

Я пытаюсь создать экземпляр COM-объекта. У меня есть имя класса, которое реализует интерфейс, и я получаю CLSID с помощью CLSIDFromProgID(). Поэтому, поскольку я получаю CLSID, я думал, что с этого момента все должно быть хорошо. Однако когда я звоню в CreateInstance и передаю в CLSID, я получаю сообщение об ошибке «Класс не зарегистрирован». Также я получаю эту ошибку только на некоторых компьютерах. Он работает без ошибок на нескольких компьютерах. Я не понимаю, где проблема. Является ли мой реестр грязным? Кто-нибудь знает, что здесь происходит? Спасибо за вашу помощь!CLSIDFromProgID успешно, но CreateInstace терпит неудачу! Зачем?

Я просто хочу добавить, что это класс .NET COM. Соответствующие записи находятся в реестре, а DLL - в GAC.

ответ

1

Спасибо за ваши ответы. Сборники .Net были зарегистрированы правильно и присутствовали в ПКК. Одно приложение, которое абсолютно подтвердило это, было Process Explorer. Вы можете просмотреть DLL, загруженные каждым приложением. Поэтому отсюда я смог узнать, действительно ли приложение, которое создавало объекты COM, могло загружать библиотеки DLL или нет. Я узнал, что это действительно происходит. Проблема была связана с различными региональными настройками. Мы обнаружили, что приложение исключило ситуацию, когда регион не был установлен в США. Эта проблема была исправлена. Сообщение об ошибке «Класс не зарегистрировано» не очень помогло. К счастью, это было быстрое решение.

1

Это двухэтапный процесс в реестре. Вы использовали ProgID для получения CLSID. Затем, когда вы вызываете CreateInstance, COM затем использует CLSID для поиска пути к dll. Вы можете использовать regedit самостоятельно для поиска CLSID и посмотреть, как выглядит эта запись.

+0

Допустим, что это класс .net COM. Тогда где это выглядит, когда я вызываю CreateInstance()? – Juba 2008-11-03 21:40:02

+1

Я считаю, никакой разницы. COM - COM. Реестр отображает CLSID в пути к DLL. – 2008-11-03 21:50:38

1

CLSIDFromProgId просто ищет имя ProgId в реестре и переводит его в CLSID, ему не нужно смотреть на что-либо за пределами реестра или даже проверять, что что-то действительно реализует этот CLSID.

Когда вы вызываете CreateInstance в CLSID, Windows будет искать в реестре, чтобы узнать, как объект должен быть создан (обычно exe или dll). Затем он попытается загрузить DLL (или запустить exe) и создать объект из него.

В MSDN имеется много документации по процессам, например, см. «COM Class Objects and CLSIDs», и если вы выполняете много работы с COM, стоит изучить процесс от первых руководителей, поскольку он может сэкономить много времени и хлопот при отладке этого типа проблемы.

+0

Допустим, что это класс .net COM. Тогда где это выглядит, когда я вызываю CreateInstance()? – Juba 2008-11-03 21:40:47

0

С помощью shell32 в качестве примера вы можете создать новый экземпляр, например:

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

Это позволит получить ссылку на существующий компонент;

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

Вот ссылка, как сделать то же самое в IronPython.

** Обратите внимание, что это использовало progid, clsid был бы почти идентичным, просто используйте Type.GetTypeFromCLSID ({GUID}).