Reputation: 22396
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;
}
}
Upvotes: 3
Views: 4782
Reputation: 12988
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.
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.
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:
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.
Upvotes: 4
Reputation: 52461
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.
Upvotes: 2