CLSIDFromProgID успешен, но CreateInstace завершается ошибкой! Зачем? - PullRequest
1 голос
/ 04 ноября 2008

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

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

Ответы [ 4 ]

1 голос
/ 04 ноября 2008

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

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

В MSDN имеется много документации по задействованным процессам, например, см. " Объекты класса COM и CLSID ", и если вы выполняете много работы с COM, стоит изучить этот процесс с самого начала. принципалы, так как это может сэкономить много времени и хлопот при отладке этого типа проблемы.

1 голос
/ 05 ноября 2008

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

1 голос
/ 04 ноября 2008

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

0 голосов
/ 16 ноября 2009

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

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

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

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

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

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

...