2009-06-02 148 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支持有沒有內置功能。

而不是調用與類ID就可以調用它的CreateInstance()方法,參數化的智能指針構造 - 它具有完全相同的一組參數,但不會拋出異常。然後,您可以檢查HRESULT並處理錯誤,並將您剛纔使用的類ID提供給錯誤處理程序。

然而,如果問題發生在您不控制的代碼中,它將無助於ypu。在極端情況下,您可以使用Process Monitor來監視註冊表查詢並檢測導致問題的哪個類ID。

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),如果我沒有記錯的權利。 – 2009-06-02 13:05:47

0

我經常用我自己的CoCreateInstance()函數的包裝,這樣,如果調用失敗,我可以再嘗試使用CLSID從註冊表查找進程id。這樣我可以至少把CLSID放入異常字符串中,但希望做得更好。我也爲接口執行此操作,因爲註冊表中的接口IID的默認字符串通常是人類可讀的名稱。查看:: StringFromGUID2()來格式化GUID。

當然,這並不能幫助您以任何方式處理第三方依賴關係。爲此,我會選擇Sharprooth對ProcessMonitor的建議(或者它的舊堂兄RegMon)。