“class not registered” which class?

拟墨画扇 提交于 2019-12-10 10:14:32

问题


Consider this code:

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

I.e. I have a block of code which instanciates my objects. Sometimes (a bad install) it failes because some class wasn't properly registered. (I don't have a particular problem, rather general discussion here.)

Is there some way to, from the caught exception or otherwise, realize what class failed? A have pondered to make a wrapper of my own which stores a variable like gLastCreateAttemptUuid, but it feel cumbersome.

Also, suppose that SomeClass in turn attempt to instanciate something else, which isn't registered. Can one then figure out the underlying issue?


回答1:


It's the duty of CoCreateInstance() caller to provide enough information about what it was trying to instantiate - both ATL and Native COM Support have no built-in features for that.

Instead of calling a smart pointer constructor parameterized with a class id you can call its CreateInstance() method - it has exactly the same set of parameters but doesn't throw exceptions. Then you could check the HRESULT and handle the error and provide the class id you just used to the error handler.

However it will not help ypu if the problem happens in the code you don't control. In extreme cases you can use Process Monitor to monitor registry queries and detect which class id is causing the problem.




回答2:


Neither CComPtr::CreateInstance nor _com_ptr_t::CreateInstance should throw an exception from what I can tell from the documentation. Both return an HRESULT value.

But if you check the HRESULT return value from each call, you should be able to determine which of the two classes are not registered (if that is the problem).

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

Check out the documentation for CoCreateInstance for return values.

Update: If you are catching an exception, then please show us any information it has. If this is the case, then my guess is that one of the classes you are trying to instantiate is throwing the error. Debugging over those lines or separating the code into two try/catch blocks would help you narrow down which one if the exception does not have any information.




回答3:


I have often used my own CoCreateInstance() function wrapper so that if the call fails I can then try and lookup the ProgID from the registry using the CLSID. This way I can at least put the CLSID into the exception string, but hope to do better. I also do this for interfaces as the default string for an interface IID in the registry is often a human readable name. Look at ::StringFromGUID2() for formatting GUIDs.

Of course this does not help you deal with 3rd party dependencies in any way. For this I would go with sharptooth's suggestion of ProcessMonitor (or it's older cousin RegMon).



来源:https://stackoverflow.com/questions/939215/class-not-registered-which-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!