使用 COM 对象上的反射调用方法
Posted
技术标签:
【中文标题】使用 COM 对象上的反射调用方法【英文标题】:Invoke method using Reflection on COM Object 【发布时间】:2011-02-15 21:53:40 【问题描述】:我有一个 COM 对象的实例......它是这样创建的:
Type type = TypeDelegator.GetTypeFromProgID("Broker.Application");
Object application = Activator.CreateInstance(type);
当我尝试调用一个方法时:
type.GetMethod("RefreshAll").Invoke(application, null);
-> type.GetMethod("RefreshAll")
返回null
。
当我尝试使用type.GetMethods()
获取所有方法时,只有这些方法:
-
GetLifetimeService
初始化LifetimeService
CreateObjRef
ToString
等于
GetHashCode
获取类型
RefreshAll 方法在哪里?我该如何调用它?
【问题讨论】:
【参考方案1】:你不能在 COM 对象上使用 GetMethod,你必须使用不同的 方式:
this.application.GetType().InvokeMember("RefreshAll", BindingFlags.InvokeMethod, null, this.application, null);
我在一个使用 COM 的旧项目中使用这种方式,所以它应该适合你。
【讨论】:
虽然在当时是一个很好的答案,但 c# 4 通过下面的dynamic
关键字可以更轻松地执行 COM 互操作
注意,由于在我的工具github.com/awaescher/RepoZ 中使用dynamic
,我发现它存在严重的内存泄漏。我切换到 Nathan W 的答案来解决这个问题!在此处查看更多信息:***.com/questions/33080252/…
在 MickyD 上查看其他 cmets 关于如何处理该问题的答案 ...【参考方案2】:
我意识到这是一个较晚的答案,但 c# 4 引入了 dynamic
关键字,该关键字在设计时考虑了 COM-interop。
MSDN:
C# 团队在 C# 4 版本中专门针对的 COM 互操作方案是针对 Microsoft Office 应用程序(例如 Word 和 Excel)进行编程。其目的是让 C# 中的这项任务像在 Visual Basic 中一样简单自然。 [1]
您的代码现在变为:
Type type = TypeDelegator.GetTypeFromProgID("Broker.Application");
dynamic application = Activator.CreateInstance(type);
application.RefreshAll(); // <---- new in c# 4
现在您不会在 Visual Studio 语句完成中看到 RefreshAll()
,所以不要惊慌。它会编译。
[1]Understanding the Dynamic Keyword in C# 4
【讨论】:
注意,由于在我的工具github.com/awaescher/RepoZ 中使用dynamic
,我发现它存在严重的内存泄漏。我切换到 Nathan W 的答案来解决这个问题!在此处查看更多信息:***.com/questions/33080252/…
@Waescher 很奇怪,考虑到 MS 首先是为 COM 设计的。我怀疑你只是没有正确发布与 dynamic 无关的东西
@Waescher 哦,我刚刚做了一些谷歌搜索,看来你是对的。讨厌的小动态。很好的发现
感谢指正。我发布的那个链接 (***.com/questions/33080252/…) 显示了我所面临的问题以及所有 RuntimeBinder 的问题。不要误会,泄漏是巨大的:i.imgur.com/5ucIcI6.png。我可能会补充一点,我经常调用包含dynamic
的方法,但无论如何......
@Waescher 不,谢谢-你。我想我没有在我的东西中注意到它,因为应用程序不会运行很长时间然后退出。希望MS能改正。 :)以上是关于使用 COM 对象上的反射调用方法的主要内容,如果未能解决你的问题,请参考以下文章