如何检测一个dll是否是一个COM dll
How to detect if a dll is a COM dll
我想确定是否需要将 dll 注册为部署工具的一部分。所以它可能是任何类型的 com dll、.net 或其他。它可能会或可能不会注册。所以这个问题和 How to determine if DLL is COM or .NET?.
有点不同
我的函数签名是:
public bool? IsComDll(string Path)
{
}
我想直接检查 dll,而不是注册它来查找,因为那样会留下副作用。
如果碰巧是 .Net dll,我不介意使用 Assembly
函数,但我不会提前知道,我也需要处理非 .Net dll。
编辑:
这是我目前的代码。除了可能是 COM 也可能不是 COM 的非 .net dll 之外,它可以正常工作,其中 LoadLibrary
是 returning 零指针,这可能是由于其他原因(如依赖性问题)造成的。某些 COM dll 工作正常并且 return 正确,例如 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;
}
}
支持自注册的 DLL(通常是 COM DLL,但不一定非得如此)会导出一个名为 DllRegisterServer
or, less commonly, DllInstall
.
的函数
您可以在 regsvr32
实用程序的帮助下手动注册此类 DLL。
有一些工具可以在开发时对此提供帮助。这些方法是手动的,但通常只构建一次安装程序,因此这种方法可以获得所需的信息。
我经常 运行 OLEView(C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\OLEVIEW.EXE
在我的系统上 - 可能带有 VB6 / Visual Studio 6 ) 并尝试打开有问题的 DLL。如果它是一个 COM DLL,OLEView 将很好地显示其 IDL 等的转储。否则它会给出一些错误。
这有点 "quick & dirty" 但对我来说效果很好。
(2020 Update) OLEView 有一个替换项目叫做 OLEViewDotNet which boasts improved features. Discussed here.
Dependency Walker (C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\DEPENDS.EXE
) 可用于检查 DLL 以查看它是否包含特征 COM 函数导出。例如,这是一个加载 mscomct2.ocx:
的示例
正如在另一个答案中指出的那样,函数 DLLRegisterServer
和 DLLUnregisterServer
是 COM DLL 的典型/必需的,因此它们的存在几乎肯定意味着它就是这样。
我想确定是否需要将 dll 注册为部署工具的一部分。所以它可能是任何类型的 com dll、.net 或其他。它可能会或可能不会注册。所以这个问题和 How to determine if DLL is COM or .NET?.
有点不同我的函数签名是:
public bool? IsComDll(string Path)
{
}
我想直接检查 dll,而不是注册它来查找,因为那样会留下副作用。
如果碰巧是 .Net dll,我不介意使用 Assembly
函数,但我不会提前知道,我也需要处理非 .Net dll。
编辑:
这是我目前的代码。除了可能是 COM 也可能不是 COM 的非 .net dll 之外,它可以正常工作,其中 LoadLibrary
是 returning 零指针,这可能是由于其他原因(如依赖性问题)造成的。某些 COM dll 工作正常并且 return 正确,例如 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;
}
}
支持自注册的 DLL(通常是 COM DLL,但不一定非得如此)会导出一个名为 DllRegisterServer
or, less commonly, DllInstall
.
您可以在 regsvr32
实用程序的帮助下手动注册此类 DLL。
有一些工具可以在开发时对此提供帮助。这些方法是手动的,但通常只构建一次安装程序,因此这种方法可以获得所需的信息。
我经常 运行 OLEView(
C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\OLEVIEW.EXE
在我的系统上 - 可能带有 VB6 / Visual Studio 6 ) 并尝试打开有问题的 DLL。如果它是一个 COM DLL,OLEView 将很好地显示其 IDL 等的转储。否则它会给出一些错误。这有点 "quick & dirty" 但对我来说效果很好。
(2020 Update) OLEView 有一个替换项目叫做 OLEViewDotNet which boasts improved features. Discussed here.
Dependency Walker (
C:\Program Files (x86)\Microsoft Visual Studio\Common\Tools\DEPENDS.EXE
) 可用于检查 DLL 以查看它是否包含特征 COM 函数导出。例如,这是一个加载 mscomct2.ocx: 的示例
正如在另一个答案中指出的那样,函数 DLLRegisterServer
和 DLLUnregisterServer
是 COM DLL 的典型/必需的,因此它们的存在几乎肯定意味着它就是这样。