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