我有一些代码使用组件类别管理器来加载实现特定类别的所有类。
是否有一种简单的方法可以从加载的DLL或EXE中获取描述,路径和版本信息?
答案 0 :(得分:1)
当对象在同一个公寓中的进程内(即从DLL中)加载时,可能会有一些技巧可以在内存中找到DLL。例如,如果您在虚拟方法表(vtable)中查找到活动对象的代码指针,它们通常会指向DLL。然后,您可以使用一些系统调用来确定代码所属的加载DLL。
但是有很多潜在的陷阱。如果必须将这些对象加载到单独的单元中,则代码指针将指向存根而不是实际代码。此外,许多COM库实际上实现了运行时提供的包装类中的公共接口,因此很可能在许多常见用例中为您提供错误信息。 (即,您最终会获得运行时DLL的信息,通常是MFC或ATL)。
当一个对象被加载到进程外(即来自EXE)时,我不知道任何合理的方法来追逐哪个EXE对应于活动对象。 (显然,这些数据必须存在于进程中的某个位置或COM运行时中,但它隐藏在存根下面的某个位置,并且可能依赖于您运行的Windows版本。)
因此,除非您正在查看一组非常有限的对象(所有在进程中加载与您相同的公寓),最好的办法是使用注册表中的注册信息来查找您需要的内容。这很麻烦,因为这是可以在操作系统版本之间发生变化的事情之一,但幸运的是,COM已经存在很长时间了,多年来这种情况并没有发生变化。
鉴于您从Component Categories Manager获得的对象的CLSID,您将按如下方式查找相应的二进制文件:
HKEY_CLASSES_ROOT\CLSID\{xxxxxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbbbbbb
} ,大括号内的字符串是您要查找的对象的CLSID。REG_SZ
包含所需DLL的完整路径。REG_SZ
包含所需EXE的完整路径。在某些情况下,您可能必须从该字符串中修剪命令行开关才能获得EXE路径。答案 1 :(得分:0)
获取此信息的一种方法是假设它仅用于记录目的,只需等待所有初始化完成,然后枚举已加载的模块,将每个模块的详细信息转储到日志文件中。
显然,这只适用于inproc对象,如果应用程序非常动态,它将无法工作,但它也会捕获非COM DLL。