【问题标题】:How to check if a COM property or method exists without generating an exception?如何在不产生异常的情况下检查 COM 属性或方法是否存在?
【发布时间】:2012-07-17 10:33:48
【问题描述】:

我正在处理一些遗留代码,它创建一个包含属性和/或方法名称的字符串列表,然后尝试将这些属性或方法应用于 COM 对象。 COM 对象的属性或方法不保证存在,它可能是我不知道的属性或方法。

目前,如果某个属性或方法不存在,则会将其作为 COM 异常捕获。这会导致性能不佳。我正在尝试找到一种方法来检查 COM 对象中是否存在属性或方法而不生成异常,以便在尝试应用它之前检查它是否存在。

使用 GetType 返回类型 System.com_object。在 System.com_object 上使用 GetProperty 不起作用,因为这是确切的运行时类型,而不是其派生的类型。相反,如果成员不存在,我必须 InvokeMember 创建一个异常。有人有更好的方法吗?

我目前正在使用 .NET 3.5。目前还不能迁移到 .NET 4,但如果新的语言功能提供了更好的解决问题的方法,我仍然会对 .NET 4 中的解决方案感兴趣。

public static bool CheckIfComPropertyOrMethodExists<T1>(T1 objectToCheck, string propertyOrMethodName)
{
    if (CheckIfComPropertyExists(objectToCheck, propertyOrMethodName) == false & CheckIfComMethodExists(objectToCheck, propertyOrMethodName) == false) {
        return false;
    }
    {
        return true;
    }
}

public static bool CheckIfComPropertyExists<T1>(T1 objectToCheck, string propertyName)
{
    return objectToCheck.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, objectToCheck, null) != null;
}

public static bool CheckIfComMethodExists<T1>(T1 objectToCheck, string methodName)
{
    return objectToCheck.GetType().GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance) != null;
}

到目前为止有用的文章

How to check whether an object has certain method/property?

Calling a member of IDispatch COM interface from C#

http://msdn.microsoft.com/en-us/library/aa909091.aspx

Implementing IDispatch in c#

http://msdn.microsoft.com/en-us/magazine/dd347981.aspx

http://blogs.msdn.com/b/lucian/archive/2008/10/06/reflection-on-com-objects.aspx

【问题讨论】:

  • 别忘了过滤掉“FormatDrive”方法。

标签: c# com .net-3.5


【解决方案1】:

COM 类很可能也实现了 IDispatch 接口。然后,您可以使用它的 GetIDsOfNames 来检查该类中是否存在成员。

这里有人用 C# 调用它:

Calling a member of IDispatch COM interface from C#

【讨论】:

  • 感谢您的回答。我认为 GetIDsOfNames 会解决这个问题。我会尽快接受你的答复。我想知道你是否介意用一个例子来扩展你的答案,因为我很难理解stackoverflow.com/questions/8068449/…。我正在尝试访问 Microsoft.Office.Interop.Excel 的成员。如果我不知道要应用 GetIDsOfNames 的类的基础类型,我如何为一个类获取 IDsOfNames?我只有一个 System.com_object。这可以是 Microsoft.Office.Interop.Excel namspce 中的任何类型
  • 你只是将你的COM对象转换为IDispatch,不管对象是什么类型,它肯定实现了IDispatch。
  • 如果成员不存在,GetIDsofNames 会引发 DISP_E_UNKNOWNNAME COM 异常。这意味着我仍然有同样的性能问题。任何想法如何无一例外地做到这一点?我尝试了以下stackoverflow.com/questions/11665813/…,但没有成功。
  • (六年后...)您可以使用 [PreserveSig] 属性标记 GetIdsOfNames,让它直接返回 HRESULT,而不会为错误情况引发异常。
猜你喜欢
  • 2014-07-12
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 2022-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多