如何检测dll是否为COM dll

时间:2015-02-03 17:24:53

标签: .net com

我想确定是否需要将dll注册为部署工具的一部分。所以它可能是任何类型的com,.net或其他。它可能会或可能不会注册。所以这个问题与How to determine if DLL is COM or .NET?略有不同。

我的功能签名是:

public bool? IsComDll(string Path)
{

}

我想直接检查dll,而不是将其注册以查找,因为这会产生副作用。

我不介意使用Assembly函数,如果碰巧是.Net dll,但我不会提前知道,我也需要处理非.Net dll。

编辑:

这是我到目前为止的代码。它的工作原理除了非.net dll可能是或不是COM,其中LoadLibrary返回一个零指针,这可能是由于其他原因,如依赖问题。有些COM dll工作正常,返回true,如C:\Windows\System32\vbscript.dll。所以我想你可以说至少75%的时间都有效。

public T GetAttribute<T>(string AssemblyPath)
{
    return GetAttribute<T>(Assembly.LoadFile(AssemblyPath));
}

public T GetAttribute<T>(Assembly Assembly)
{
    return Assembly.GetCustomAttributes(typeof(T), false).FirstOrDefault;
}

public bool? IsComDll(string Path)
{

    if (IsDotNetDll(Path)) {
        ComVisibleAttribute ComVisibleAttribute = GetAttribute<ComVisibleAttribute>(Path);
        return ComVisibleAttribute != null && ComVisibleAttribute.Value;
    }

    if (Path.Contains(" ")) {
        Path = string.Format("\"{0}\"", Path);
    }

    IntPtr hModuleDLL = LoadLibrary(Path);

    if (hModuleDLL == IntPtr.Zero) {
        //we can't tell
        //TODO: Find out how!
    }

    // Obtain the required exported API.
    IntPtr pExportedFunction = IntPtr.Zero;

    pExportedFunction = GetProcAddress(hModuleDLL, "DllRegisterServer");

    return pExportedFunction != IntPtr.Zero;

}

public bool IsDotNetDll(string Path)
{
    try {
        Assembly.LoadFile(Path);
        return true;
    } catch (BadImageFormatException bifx) {
        return false;
    } catch (Exception ex) {
        throw;
    }
}

2 个答案:

答案 0 :(得分:2)

支持自行注册的DLL(通常是COM DLL,但不一定非必须)会导出名为DllRegisterServer的函数,或者不太常见的DllInstall

您可以在regsvr32实用程序的帮助下手动注册此类DLL。

答案 1 :(得分:1)

有一些工具可以在开发时帮助解决这个问题。这些方法是手动的,但通常只安装一次安装程序,因此这种方法可以获得所需的信息。

  1. 我经常在我的系统上运行 OLEView C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\OLEVIEW.EXE - 可能附带VB6 / Visual Studio 6)并尝试打开有问题的DLL。如果它是一个COM DLL,OLEView将很好地显示其IDL转储等。否则它会给出一些错误。

    这是&#34;快速&amp;脏&#34;但对我来说效果很好。

  2. Dependency Walker C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\DEPENDS.EXE)可用于检查DLL是否包含特征COM函数导出。例如,这是一个加载mscomct2.ocx的例子:

  3. enter image description here

    正如另一个回答所述,函数DLLRegisterServer和DLLUnregisterServer是COM DLL的典型/必需函数,因此它们的存在几乎肯定意味着它是什么。