【发布时间】:2008-10-14 15:13:12
【问题描述】:
我继承了一个 .NET 应用程序,该应用程序汇集了大约 100 个由两个团队构建或从供应商处购买的 dll。我想快速确定给定的 dll 是 .NET 程序集还是 COM 组件。我意识到我可以单独在每个 dll 上调用 ildasm 并在 dll 没有有效的 CLR 标头时做一个记录,但是这种方法看起来很笨拙且难以自动化。
【问题讨论】:
我继承了一个 .NET 应用程序,该应用程序汇集了大约 100 个由两个团队构建或从供应商处购买的 dll。我想快速确定给定的 dll 是 .NET 程序集还是 COM 组件。我意识到我可以单独在每个 dll 上调用 ildasm 并在 dll 没有有效的 CLR 标头时做一个记录,但是这种方法看起来很笨拙且难以自动化。
【问题讨论】:
如果您想从 COM 端接近,在 DLL 中测试 COM 对象归结为寻找名为“DllGetClassObject”的导出。这是因为 COM 运行时通过在该 DLL 上调用 DllGetClassObject() 来访问进程内 COM 对象。
您可以使用 Visual Studio 附带的DUMPBIN.EXE 从批处理文件中执行此操作,如下所示:
dumpbin unknown.dll /exports | find "DllGetClassObject"
如果是包含 COM 对象的非托管 DLL,上述命令行将生成一行文本,否则将生成零字节的输出。
您可以通过加载每个 DLL 并尝试在该入口点上执行 GetProcAddress() 以编程方式执行此操作。这是一个使用此技术的经过测试且可运行的 C# 命令行程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
static class NativeStuff
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
namespace IsComDLL
{
class Program
{
static void Main(string[] args)
{
if ( (args.Length == 0 ) || String.IsNullOrEmpty( args[0] ) )
{
Console.WriteLine( "Give DLL name on command line" );
Environment.Exit(255);
}
IntPtr pDll = NativeStuff.LoadLibrary(args[0]);
if ( pDll == IntPtr.Zero )
{
Console.WriteLine( "DLL file {0} not found", args[0] );
Environment.Exit(256);
}
IntPtr pFunction = NativeStuff.GetProcAddress(pDll, "DllGetClassObject");
int exitValue = 0;
if (pFunction == IntPtr.Zero)
{
Console.WriteLine("DLL file {0} does NOT contain COM objects", args[0]);
}
else
{
Console.WriteLine("DLL file {0} does contain COM objects", args[0]);
exitValue = 1;
}
NativeStuff.FreeLibrary(pDll);
Environment.Exit(exitValue);
}
}
}
【讨论】:
您始终可以尝试将“程序集版本”列添加到资源管理器窗口,并注意哪些是空白的以查找非 .NET 程序集。
【讨论】:
System.Reflection.Assembly.ReflectionOnlyLoadFrom("mydll.dll")
将返回对 .NET dll 的有效程序集引用,但会为 COM dll 引发错误。
【讨论】: