显示已加载COM对象的路径/版本信息?

时间:2008-10-07 11:06:03

标签: com

我有一些代码使用组件类别管理器来加载实现特定类别的所有类。

是否有一种简单的方法可以从加载的DLL或EXE中获取描述,路径和版本信息?

2 个答案:

答案 0 :(得分:1)

当对象在同一个公寓中的进程内(即从DLL中)加载时,可能会有一些技巧可以在内存中找到DLL。例如,如果您在虚拟方法表(vtable)中查找到活动对象的代码指针,它们通常会指向DLL。然后,您可以使用一些系统调用来确定代码所属的加载DLL。

但是有很多潜在的陷阱。如果必须将这些对象加载到单独的单元中,则代码指针将指向存根而不是实际代码。此外,许多COM库实际上实现了运行时提供的包装类中的公共接口,因此很可能在许多常见用例中为您提供错误信息。 (即,您最终会获得运行时DLL的信息,通常是MFC或ATL)。

当一个对象被加载到进程外(即来自EXE)时,我不知道任何合理的方法来追逐哪个EXE对应于活动对象。 (显然,这些数据必须存在于进程中的某个位置或COM运行时中,但它隐藏在存根下面的某个位置,并且可能依赖于您运行的Windows版本。)

因此,除非您正在查看一组非常有限的对象(所有在进程中加载​​与您相同的公寓),最好的办法是使用注册表中的注册信息来查找您需要的内容。这很麻烦,因为这是可以在操作系统版本之间发生变化的事情之一,但幸运的是,COM已经存在很长时间了,多年来这种情况并没有发生变化。

鉴于您从Component Categories Manager获得的对象的CLSID,您将按如下方式查找相应的二进制文件:

  1. 打开注册表项 HKEY_CLASSES_ROOT\CLSID\{xxxxxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbbbbbb} ,大​​括号内的字符串是您要查找的对象的CLSID。
  2. 如果这是一个进程内对象,则会有一个名为InProcServer32的子键,其“默认”REG_SZ包含所需DLL的完整路径。
  3. 如果这是一个out-of-proc对象,则会有一个名为LocalServer32的子键,其“默认”REG_SZ包含所需EXE的完整路径。在某些情况下,您可能必须从该字符串中修剪命令行开关才能获得EXE路径。
  4. 使用前面步骤中的DLL或EXE,您可以在Win32中调用GetFileVersionInfo()(如果您有可用的.NET,则使用System.Diagnostics.FileVersionInfo.GetVersionInfo)从可执行文件中检索版本信息结构,这将是有版本和描述。

答案 1 :(得分:0)

获取此信息的一种方法是假设它仅用于记录目的,只需等待所有初始化完成,然后枚举已加载的模块,将每个模块的详细信息转储到日志文件中。

显然,这只适用于inproc对象,如果应用程序非常动态,它将无法工作,但它也会捕获非COM DLL。