"класс не зарегистрирован" какой класс? - PullRequest
3 голосов
/ 02 июня 2009

Рассмотрим этот код:

try {
    ISomeObject pObj(__uuidof(SomeClass));
    ISomeObject pObj2(__uuidof(SomeOtherClass));
} catch ( _com_error& e ) {
    // Log what failed
}

т.е. У меня есть блок кода, который создает мои объекты. Иногда (неудачная установка) происходит сбой, потому что какой-то класс не был должным образом зарегистрирован. (У меня нет особой проблемы, здесь достаточно общего обсуждения.)

Есть ли какой-нибудь способ, из пойманного исключения или иным образом, понять, какой класс провалился? Я задумался сделать свою собственную обертку, которая хранит переменную типа gLastCreateAttemptUuid , но она кажется громоздкой.

Также предположим, что SomeClass, в свою очередь, пытается создать что-то еще, что не зарегистрировано. Можно ли тогда выяснить основную проблему?

Ответы [ 3 ]

1 голос
/ 02 июня 2009

Ни то, ни другое CComPtr::CreateInstance<code></a> nor <a href="http://msdn.microsoft.com/en-us/library/k2cy7zfz(VS.80).aspx" rel="nofollow noreferrer"><code>_com_ptr_t::CreateInstance не должно вызывать исключения из того, что я могу сказать из документации. Оба возвращают значение HRESULT.

Но если вы проверите возвращаемое значение HRESULT при каждом вызове, вы сможете определить, какой из двух классов не зарегистрирован (если это проблема).

try {
    ISomeObject pObj, pObj2;
    HRESULT hr1 = pObj.CreateInstance(__uuidof(SomeClass));
    HRESULT hr2 = pObj2.CreateInstance(__uuidof(SomeOtherClass));
} catch ( _com_error& e ) {
    // Log what failed
}
</code>

Ознакомьтесь с документацией для CoCreateInstance для возвращаемых значений.

Обновление: Если вы ловите исключение, пожалуйста, покажите нам любую имеющуюся информацию. Если это так, то я предполагаю, что один из классов, который вы пытаетесь создать, выдает ошибку. Отладка по этим строкам или разделение кода на два блока try / catch поможет вам определить, какой из них, если исключение не содержит никакой информации.

0 голосов
/ 04 июня 2009

Я часто использовал свою собственную оболочку функции CoCreateInstance (), чтобы в случае сбоя вызова я мог попытаться найти ProgID в реестре, используя CLSID. Таким образом, я могу по крайней мере поместить CLSID в строку исключения, но надеюсь, что получится лучше. Я также делаю это для интерфейсов, так как строка по умолчанию для идентификатора интерфейса в реестре часто представляет собой удобочитаемое имя. Посмотрите на :: StringFromGUID2 () для форматирования GUID.

Конечно, это никак не поможет вам справиться со сторонними зависимостями. Для этого я бы согласился с советником Шиптуса о ProcessMonitor (или его старшем двоюродном брате RegMon).

0 голосов
/ 02 июня 2009

Вызывающий объект CoCreateInstance () обязан предоставить достаточно информации о том, что он пытался создать - и ATL, и собственная поддержка COM не имеют встроенных функций для этого.

Вместо вызова конструктора интеллектуальных указателей, параметризованного идентификатором класса, вы можете вызвать его метод CreateInstance () - он имеет точно такой же набор параметров, но не вызывает исключений. Затем вы можете проверить HRESULT, обработать ошибку и предоставить идентификатор класса, который вы только что использовали для обработчика ошибок.

Однако это не поможет ypu, если проблема возникнет в коде, который вы не контролируете. В крайних случаях вы можете использовать Process Monitor для мониторинга запросов реестра и определения того, какой идентификатор класса вызывает проблему.

...