我继承了一个.NET应用程序,它将两个团队构建的100个dll组合在一起,或者从供应商那里购买。我想快速确定给定的dll是.NET程序集还是COM组件。我意识到我可以单独调用每个dll上的ildasm并记下dll是否没有有效的CLR头,但这种方法看起来很笨拙并且难以自动化。
答案 0 :(得分:3)
您始终可以尝试将“程序集版本”列添加到资源管理器窗口,并注意哪些是空白以查找非.NET程序集。
答案 1 :(得分:3)
如果你想从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);
}
}
}
答案 2 :(得分:0)
System.Reflection.Assembly.ReflectionOnlyLoadFrom("mydll.dll")
将返回对.NET dll的有效程序集引用,但会为COM dll引发错误。