3

I want to identify if a dll needs to be registered as part of a deployment tool. So it might be any kind of com dll, .net or otherwise. It may or may not be registered. So this question is a little different than How to determine if DLL is COM or .NET?.

My function signature would be:

public bool? IsComDll(string Path)
{

}

I want to inspect the dll directly, not register it to find out, because that would leave a side effect.

I don't mind using Assembly functions if it happens to be a .Net dll, but I won't know in advance and I need to handle non .Net dlls as well.

Edit:

Here is the code I have so far. It's working except on non .net dlls that may or may not be COM, where LoadLibrary is returning a zero pointer which may be because of other reasons like a dependency problem. Some COM dll's work ok and return true, like C:\Windows\System32\vbscript.dll. So I guess you could say it works at least 75% of the time.

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;
    }
}
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
toddmo
  • 20,682
  • 14
  • 97
  • 107
  • 1
    possible duplicate of [How can I detect the type of a dll? (COM, .NET, WIN32)](http://stackoverflow.com/questions/1420726/how-can-i-detect-the-type-of-a-dll-com-net-win32) – stuartd Feb 03 '15 at 17:48
  • @stuartd, the referenced question does not resolve to code. I think my question can, and thus improve on that. – toddmo Feb 03 '15 at 17:51
  • If a DLL exports a function named `DllRegisterServer`, then chances are high it expects "to be registered as part of a deployment tool." Another (much less) popular choice is `DllInstall`. Both are supported by [`Regsvr32`](https://technet.microsoft.com/en-us/library/bb490985.aspx) utility. – Igor Tandetnik Feb 04 '15 at 04:59
  • @IgorTandetnik, someone said `DllGetClassObject` will always be there. Do you think what they said is incorrect? Thanks. – toddmo Feb 04 '15 at 16:54
  • Yes, a COM DLL would always export `DllGetClassObject` - but I don't see how that fact helps with your goal of "register[ing it] as part of a deployment tool." Suppose you checked a DLL and discovered that it does in fact export `DllGetClassObject` - now what? – Igor Tandetnik Feb 04 '15 at 17:31
  • @IgorTandetnik, I see what you are saying. If you post an answer, I'll mark it. Then maybe you can reverse the down vote? – toddmo Feb 05 '15 at 16:06
  • I can't reverse what I didn't give in the first place. – Igor Tandetnik Feb 05 '15 at 19:26
  • @IgorTandetnik, I'll mark your answer if you want. Thanks again! – toddmo Feb 06 '15 at 00:19

2 Answers2

4

There are a few tools which can assist with this at development-time. These approaches are manual but generally an installer is only built once so this kind of approach can get the information needed.

  1. I often run OLEView (C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\OLEVIEW.EXE on my system - might have come with VB6 / Visual Studio 6) and try to open the DLL in question. If it is a COM DLL, the OLEView will nicely display a dump of its IDL etc. Otherwise it gives some error.

    This is kind of "quick & dirty" but has worked well for me.

    (2020 Update) There is a replacement project for OLEView called OLEViewDotNet which boasts improved features. Discussed here.

  2. Dependency Walker (C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\DEPENDS.EXE) can be used to inspect the DLL to see if it contains characteristic COM function exports. For instance, here's an example of loading mscomct2.ocx:

enter image description here

As noted in another answer the functions DLLRegisterServer and DLLUnregisterServer are typical / required for COM DLLs and so their existence almost certainly means that's what it is.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
2

A DLL that supports self-registration (usually a COM DLL, but doesn't strictly have to be) would export a function named DllRegisterServer or, less commonly, DllInstall.

You can manually register such DLLs with the help of regsvr32 utility.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85