2012-10-23 54 views
2
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,则表示它不能在运行时绑定到空对象(基本上是同一件事)。如何通过ProgID以C反射调用COM对象#

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

+0

你的意思是像'device.InvokeMethod(Name);'?哦,哼,我又做了。方法名称在编译时不知道。 –

+0

我的意思是我甚至不知道在编译时会调用哪些方法。我现在知道的唯一原因就是测试。我有一个设备需要实现的接口,但这只与测试有关,只要它存在,程序就不会小心。 –

回答

0

嗯,我想我终于明白了,这要归功于这个答案:https://stackoverflow.com/a/3199919/258482。问题是你必须使用InvokeMember来对COM对象做任何事情。

+0

虽然这是一个很好的答案,但c#4使得通过'dynamic'关键字执行COM-interop变得更容易,所以不需要'InvokeMember'。请参阅我在该链接上的回答 – MickyD

0

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

检查:

  • 是所述取消搁置方法确实写有一个大写的U?
  • 是否需要object []参数?
+0

我认为这是需要这些对象的反射。 –