2009-06-02 2 views
3

Рассмотрим этот код:"класс не зарегистрирован", какой класс?

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

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

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

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

ответ

0

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

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

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

1

Ни CComPtr::CreateInstance, ни _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 } 

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

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

+0

Тот факт, что _com_error попадает, означает, что OP не использует ATL, но вместо этого использует «встроенную поддержку COM» (_com_ptr_t), если я правильно помню. –

0

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

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