ComObject 可视化工具






4.77/5 (12投票s)
Visual Studio 对象可视化工具,用于类型为 System.__ComObject 的对象

引言
最近我参与了一个处理 Excel 和 PowerPoint 应用程序的项目,遇到了在调试时无法查看 COM 对象类型的问题。我尝试使用 GetType
,但它返回一个 __ComObject
,而它本身不包含关于底层接口的任何有用的信息。
我决定为 Visual Studio 创建一个 可视化工具,它有助于在调试时处理 COM 对象。因此,本文将描述一种识别 COM 对象支持的接口的方法。
背景
以下是一个在 Excel 中查找形状并将其转换为 Office.Forms
的 TextBox
控件的代码示例:
using Microsoft.Office.Interop.Excel;
using TextBox=Microsoft.Vbe.Interop.Forms.TextBox;
...
Shape shape = sheet.Shapes.Item("ctool");
OLEObject oleObject = (OLEObject) shape.OLEFormat.Object;
TextBox TextBox = (TextBox) oleObject.Object;
...
这段代码很简单,但我花了很多时间才找到一种方法。造成这种情况的原因有两个问题:
- 在互联网上,他们建议以这种方式处理
Office.Forms
控件:Shape shape = sheet.Shapes.Item("ctool"); TextBox TextBox = (TextBox) shape.OLEFormat.Object;
尽管有建议,这段代码抛出了“
无法转换
”异常。 - 仅使用基本工具,在 VS 中识别 COM 对象的底层类型并不容易。
Using the Code
类型识别的主要思想与 IUnknown
接口有关。所有 COM 对象都支持此接口,并且具有 QueryInterface
方法。要识别支持的接口,需要迭代所有当前加载的接口,并查询 COM 对象是否支持它。以下是执行此操作的 ComObjectSource
类的源代码。
public class ComObjectSource : VisualizerObjectSource
{
public override void GetData(object target, Stream outgoingData)
{
Assembly[] assemblies = Thread.GetDomain().GetAssemblies();
List<type> types = new List<type>();
foreach (Assembly assembly in assemblies)
{
types.AddRange(
FindInterfaceTypesForComObject(assembly, target));
}
new BinaryFormatter().Serialize(outgoingData, types);
}
public IEnumerable<type> FindInterfaceTypesForComObject
(Assembly Assembly, object ComObject)
{
IntPtr iuknw = Marshal.GetIUnknownForObject(ComObject);
foreach (Type type in Assembly.GetTypes())
{
Guid uid;
if (!type.IsInterface ||
(uid = type.GUID) == Guid.Empty)
{
continue;
}
IntPtr ipointer = IntPtr.Zero;
Marshal.QueryInterface(iuknw, ref uid, out ipointer);
if (ipointer != IntPtr.Zero)
{
yield return type;
}
}
}
}
要为 System.__ComObject
类型注册可视化工具,您需要添加以下内容:
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Visualizer),
typeof(ComObjectSource),
TargetTypeName = "System.__ComObject, mscorlib,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
Description = "ComObject Visualizer")]
为了使用此可视化工具,您需要将 *.dll 文件放入 <Visual Studio 安装目录>\Common7\Packages\Debugger\Visualizers 或 <我的文档目录>\Visual Studio 2005\Visualizers。
关注点
我不再花更多时间来识别 COM 对象的类型。所以我也希望你也是如此。;-)
历史
- [2008-02-21] - 文章的初始发布