如何使用C#检查COM DLL是否已注册?

9

我需要检查在我运行的计算机系统上是否已经注册了msdia100.dll,以便使用命令regsvr32.exe注册该dll。如何使用C#实现?

6个回答

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;
    }
}

4

注册表方法是可以的,值得尝试。但为确保安全,您还可以在COM对象中实例化try {} catch (COMException) {},如果捕获到COMException,则向用户呈现合理的内容。


特别是因为注册表比看起来复杂得多,由于各种仿真层、32/64位等。 - Steven Sudit

3
你可以在注册表中搜索此信息。假设你不知道DLL文件中包含的COM对象,那么你首先需要在 HKEY_CLASSES_ROOT 中查找DLL名称。
然后使用类名在 HKEY_CLASSES_ROOT\[ClassName]\CLSID 中查找CLSID,最后你应该能够在 HKEY_CLASSES_ROOT\CLSID\[CLSID] 中找到它。
请注意,这些注册表位置是根据记忆写下来的,可能会有一些错误。
编辑:或者,如果你知道类名,你可以尝试创建一个实例并查看它是否可用。

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;

1

查看 HKEY_CLASSES_ROOT\CLSID\\InprocServer 的注册表。如果您有该记录,则 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);    
}

我不相信这是正确的。它加载任何DLL,无论它是否已注册为托管COM对象。 - Steven Sudit
@Steve,你正在通过名称而不是完整路径加载一个dll。如果dll被加载了,那么它已经被注册了。如果没有被加载,那么它就没有被注册。除非你要找的dll也恰好在你的路径中。 - Shiv Kumar
只是为了明确起见,LoadLibrary后跟着DllGetClassObject(带有接口的CLSID和IID)会给你一个可以操作的COM对象实例。如果加载库失败,它就不会工作,没有任何例外。 - Shiv Kumar
2
如果 DLL 被加载了,那是因为在路径上找到了该 DLL。如果你将 DLL 放入当前目录或 C:\Windows\System32 或任何其他可以找到的地方,那么 LoadLibrary 就会起作用。此时,DllGetClassObject 也会起作用,但这并没有告诉我们什么。谁给你点赞是错了的。 - Steven Sudit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接