在System .__ ComObject上调用GetMethod()始终返回null [英] Invoking GetMethod() on a System.__ComObject always returns null

查看:82
本文介绍了在System .__ ComObject上调用GetMethod()始终返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.NET 4.0和dynamic在运行时在System .__ ComObject上调用成员.我通过以下方式实例化该对象:

I am using .NET 4.0 and dynamic to invoke members on a System.__ComObject at runtime. I instanciate the object in the following way:

dynamic DrApi;
DrApi = Activator.CreateInstance(SprImportedTypes.DrApi);

在静态类中声明类型,如下所示:

The types are declared in a static class like this:

internal static Type DrApi = Type.GetTypeFromProgID("DrApi.DrApi.1");

由于对象是动态的,因此我可以毫无困难地调用方法:

Since the object is dynamic, I can invoke methods without any difficulty:

string vers = string.Empty;
DrApi.Version(ref vers);

对于合并和本地化的错误处理,我正在尝试使用一个例程来对该对象上的方法进行调用.大多数方法都需要ref/out参数,因此我目前正在返回从反射中返回值的对象数组:

For consolidation and localized error handling, I'm trying to have a single routine that can be used for invoking methods on that object. Most of the methods require ref/out parameters, so I'm currently returning an object array of values that gets returned from reflection:

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;
}

虽然可行,但我没有得到有关所用方法的任何信息,因此不能百分百地通过引用设置所有参数.

While this works, I'm not getting any information on the method I'm invoking, and am therefore not 100% comfortable setting all of the parameters by reference.

这是我尝试过的不起作用的地方:

Here's what I tried that isn't working:

MethodInfo mInfo = SprImportedTypes.DrApi.GetMethod(methodName, BindingFlags.Instance |
                                                    BindingFlags.NonPublic | BindingFlags.Static);

这是OLE TypeLib Viewer中的方法:

Here is the method from OLE TypeLib Viewer:

[id(0x00000009), helpstring("method Version")]
HRESULT Version(
            [in, out] BSTR* VersionString, 
            [out, retval] long* pReturnValue);

该类实现了一个接口,该接口本身实现了IDispatch,方法为HRESULT,因此我无法弄清楚为什么它从不返回任何内容.

The class implements an interface which itself implements IDispatch, and the method is HRESULT, so I can't figure out why it never returns anything.

推荐答案

这无法正常工作,COM 支持反射.因此,您不能期望Type.GetMethod()返回任何内容.在COM中后期绑定是一种单向方式,您可以要求服务器按名称执行方法,但不会告诉您它支持什么方法以及它们采用什么参数.您应该从文档中知道这一点.

This cannot work, COM does not support Reflection. So you cannot expect Type.GetMethod() to return anything. Late binding in COM is one-way, you can ask the server to execute a method by name but it won't tell you what methods it supports and what arguments they take. You are supposed to know this from the documentation.

您实际上有一个类型库,因此从技术上 您可以在运行时对其进行检查以查看其内部内容.这远远超出痛苦且完全不切实际.简单得多就是只添加对类型库的引用.您将获得自动生成的.NET包装器类型,可以直接在代码中使用.有关详细信息,请查看有关Tlbimp.exe的MSDN文章.这会带来很多好处,例如IntelliSense和编译时错误检查.该代码的运行速度也快得多.不再需要 dynamic .唯一的缺点是,您会将代码绑定到特定版本的COM服务器,该版本具有您的类型库.但是,当后期绑定的电话与更新不兼容时,您当然仍然会崩溃,对此没有灵丹妙药.

You actually have a type library so technically you can inspect it at runtime to see what it is inside. This is far beyond painful and utterly impractical. Far simpler is to just add a reference to the type library. And you'll get auto-generated .NET wrapper types that you can use directly in your code. Check the MSDN article about Tlbimp.exe for details. This turns on lots of goodies, like IntelliSense and compile-time error checking. The code runs a lot faster as well. No need for dynamic anymore. The only disadvantage is that you'll bind your code to a specific version of the COM server, the one you have the type library for. But you'll of course still crash when your late-bound call is not compatible with an update, there is no magic cure for that.

这篇关于在System .__ ComObject上调用GetMethod()始终返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆