2011-02-11 136 views

回答

3

您可以通過註冊表進行搜索。假設您不知道DLL中包含的COM對象,則必須先開始在HKEY_CLASSES_ROOT中查找DLL名稱。

然後使用類名來查找HKEY_CLASSES_ROOT\[ClassName]\CLSID中的CLSID,最後您應該能夠找到它作爲HKEY_CLASSES_ROOT\CLSID\[CLSID]的CLSID。

請注意,從內存中寫入的註冊表位置可能會有點偏離。

編輯:或者,如果您知道類名稱,您可以嘗試創建它的一個實例並查看它是否有效。

1

查看位於HKEY_CLASSES_ROOT \ CLSID \\ InprocServer的rgistry。如果你有這個記錄,那麼這個DLL應該被註冊。

-1

這是正確的做法。它確實涉及PInvoke,但這只是因爲它們沒有直接在.NET中提供這種功能。

[DllImport("kernel32")]  
public extern static int LoadLibrary(string lpLibFileName); 

[DllImport("kernel32")]  
public extern static bool FreeLibrary(int hLibModule);   

public bool IsDllRegistered(string DllName)  
{  
    int libId = LoadLibrary(DllName); 
    if (libId>0) FreeLibrary(libId); 
    return (libId>0);  
} 
+0

我不相信這是完全正確的。它加載*任何* DLL,無論它是否註冊爲託管COM對象。 – 2011-02-11 09:00:26

+0

@Steve,你正在加載一個DLL的名稱,而不是一個完整的路徑。如果該DLL加載它已被註冊。如果沒有,它還沒有被註冊。除非你正在尋找的DLL也碰巧在你的路上。 – 2011-02-11 09:32:48

+0

爲了清楚起見,LoadLibrary後跟DllGetClassObject(帶有CLSID和接口的IID)爲您提供了一個可以使用的COM對象的實例。如果加載庫失敗,那麼這段時間不起作用。 – 2011-02-11 09:44:29

4

註冊表的方法是可以的,值得做的事情,但可以肯定,你也可以考慮從包裝在一個try {}趕上COM對象中實例化的東西(收到COMException){},那麼現在一些明智的用戶是否遇到COMException。

2

驗證是否使用Microsoft.Win32.RegistryKey

var key = Microsoft.Win32.RegistryKey.OpenBaseKey(
      Microsoft.Win32.RegistryHive.ClassesRoot, 
      Microsoft.Win32.RegistryView.Default) 
      .OpenSubKey("Interface") 
       //replace with your COM object GUID 
      .OpenSubKey("{a3560000-0000-0000-c63b3-000000cbadf0000}"); 

     return key != null; 
4

假設你知道COM DLL的CLSID存在鍵,你可以檢查是否有與上CLSID的關鍵HKEY_CLASSES_ROOT\CLSID\{CLSID-of-your-COM-component}HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{CLSID-of-your-COM-component}(Wow6432Node =>在64位機器上註冊的32位COM)

例如

private bool IsAlreadyRegistered() 
{ 
    using (var classesRootKey = Microsoft.Win32.RegistryKey.OpenBaseKey(
      Microsoft.Win32.RegistryHive.ClassesRoot, Microsoft.Win32.RegistryView.Default)) 
    { 
     const string clsid = "{12345678-9012-3456-7890-123456789012}"; 

     var clsIdKey = classesRootKey.OpenSubKey(@"Wow6432Node\CLSID\" + clsid) ?? 
         classesRootKey.OpenSubKey(@"CLSID\" + clsid); 

     if (clsIdKey != null) 
     { 
      clsIdKey.Dispose(); 
      return true; 
     } 

     return false; 
    } 
}