【发布时间】:2015-02-03 17:24:53
【问题描述】:
我想确定是否需要将 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 的非 .net dll 上,它可以工作,其中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;
}
}
【问题讨论】:
-
@stuartd,引用的问题无法解析为代码。我认为我的问题可以,因此可以改进。
-
如果 DLL 导出一个名为
DllRegisterServer的函数,那么它期望“被注册为部署工具的一部分”的可能性很高。另一个(少得多)流行的选择是DllInstall。Regsvr32实用程序支持两者。 -
@IgorTandetnik,有人说
DllGetClassObject将永远存在。你觉得他们说的不对吗?谢谢。 -
是的,COM DLL 总是会导出
DllGetClassObject- 但我看不出这个事实如何帮助您实现“将它注册为部署工具的一部分”的目标。假设您检查了一个 DLL 并发现它实际上导出了DllGetClassObject- 现在怎么办?