我正在使用.NET 4.0和动态来在运行时调用System .__ ComObject上的成员。我以下列方式实例化对象:
dynamic DrApi;
DrApi = Activator.CreateInstance(SprImportedTypes.DrApi);
类型在静态类中声明,如下所示:
internal static Type DrApi = Type.GetTypeFromProgID("DrApi.DrApi.1");
由于对象是动态的,我可以毫无困难地调用方法:
string vers = string.Empty;
DrApi.Version(ref vers);
对于合并和本地化错误处理,我正在尝试使用一个可用于在该对象上调用方法的例程。大多数方法都需要ref / out参数,所以我当前正在返回一个从反射中返回的值的对象数组:
public object[] Run(string method, params object[] args)
{
var p = new ParameterModifier(args.Length);
for (int i = 0; i < args.Length; i++)
p[i] = true;
ParameterModifier[] mods = { p };
SprImportedTypes.DrApi.InvokeMember(method, BindingFlags.InvokeMethod,
null, DrApi, args, mods, null, null));
return args;
}
虽然这有效,但我没有获得有关我正在调用的方法的任何信息,因此我不能100%通过引用设置所有参数。
这是我尝试过的不起作用:
MethodInfo mInfo = SprImportedTypes.DrApi.GetMethod(methodName, BindingFlags.Instance |
BindingFlags.NonPublic | BindingFlags.Static);
以下是OLE TypeLib Viewer中的方法:
[id(0x00000009), helpstring("method Version")]
HRESULT Version(
[in, out] BSTR* VersionString,
[out, retval] long* pReturnValue);
该类实现了一个本身实现IDispatch的接口,该方法是HRESULT,所以我无法弄清楚为什么它永远不会返回任何东西。
答案 0 :(得分:2)
这不起作用,COM 不支持Reflection。所以你不能指望Type.GetMethod()返回任何东西。 COM中的后期绑定是单向的,您可以要求服务器按名称执行方法,但它不会告诉您它支持哪些方法以及它们采用的参数。您应该从文档中了解这一点。
你实际上有一个类型库,所以技术上你可以在运行时检查它,看看里面是什么。这远远超出痛苦和完全不切实际。更简单的是只添加对类型库的引用。并且您将获得可以直接在代码中使用的自动生成的.NET包装类型。有关详细信息,请查看有关Tlbimp.exe的MSDN文章。这会打开很多好东西,比如IntelliSense和编译时错误检查。代码也运行得更快。不再需要动态。唯一的缺点是您将代码绑定到COM服务器的特定版本,即具有类型库的COM服务器。但是当你的后期通话与更新不兼容时,你当然会崩溃,没有神奇的解决办法。