【问题标题】:How to call a COM Object by ProgID with Reflection in C#如何在 C# 中通过带有反射的 ProgID 调用 COM 对象
【发布时间】:2012-10-13 15:02:06
【问题描述】:
class Device{
    private object device;
    public Device(string ProgID)
    {
        if (ProgID == "") ProgID = "ScopeSim.Telescope";
        device = Activator.CreateInstance(Type.GetTypeFromProgID(ProgID));
        Console.WriteLine("Connected");
    }
    public object Invoke(string Name, object[] args)
    {
        var v1 = device.GetType(); //this is a com object in debug
        var v2 = v1.GetMethod(Name);
        var v3 = v2.Invoke(device,args); //throws exception, v2 is null
        return v3;
    }
}
//somwhere else in another method in another class that has this in a field...
Console.WriteLine(new Device("").Invoke("A Method Name that is a string but is not known and could be anything, for testing, the name is 'Unpark'", object[] args));

这会引发NullReferenceException。 Unpark 方法确实存在,但它没有返回类型,但它确实存在。此外,当它停止调试(异常)时,构造函数中的 ProgID 字段为空。我会认为这是正常的,对吧?它应该已经运行了。有谁知道它为什么会抛出它?如果我将设备声明为dynamic,则表示它不能在运行时绑定到空对象(基本上是同一件事)。

对第一个答案的回应:我认为反射需要将变量作为对象数组。是的,Unpark 是用大写的 U 编写的。ProgID 的东西显然似乎无关紧要。

【问题讨论】:

  • 你的意思是像device.InvokeMethod(Name);?哦,嗯,​​我又做了一次。编译时方法名未知。
  • 我的意思是我什至不知道在编译时会调用什么方法。我现在知道它的唯一原因是为了测试。我有一个设备需要实现的接口,但这仅与测试相关,只要它存在,程序就不会关心。

标签: c# .net-4.0


【解决方案1】:

好吧,如果 ProgID 是null,它不会被设置,因为你只检查字符串是否为空。我总是使用string.IsNullOrEmpty(s) 而不是s == ""

检查一下:

  • Unpark 方法真的是用大写的 U 编写的吗?
  • 是否需要 object[] 参数?

【讨论】:

  • 我认为反射需要这些对象。
【解决方案2】:

好吧,我想我终于弄明白了,感谢这个答案:https://stackoverflow.com/a/3199919/258482。问题是您必须使用InvokeMember 对 COM 对象执行任何操作。

【讨论】:

  • 虽然当时是一个很好的答案,但 c# 4 使得通过 dynamic 关键字执行 COM 互操作变得更加容易,因此不需要 InvokeMember。在该链接上查看我的答案
猜你喜欢
  • 1970-01-01
  • 2010-11-18
  • 2012-11-01
  • 1970-01-01
  • 2012-08-08
  • 2020-06-17
  • 2012-05-23
  • 2013-03-23
  • 1970-01-01
相关资源
最近更新 更多