C#动态COM对象可以';找不到方法
我试图通过C#访问COM对象(CST Studio套件)。我以前曾通过以下MATLAB脚本成功访问和控制此对象:C#动态COM对象可以';找不到方法,c#,matlab,com,C#,Matlab,Com,我试图通过C#访问COM对象(CST Studio套件)。我以前曾通过以下MATLAB脚本成功访问和控制此对象: CST = actxserver('CSTStudio.Application'); % Opens CST CST.FileNew(); % Creates a new file MWS = CST.Active3D; % Set focus to the new file MWS
CST = actxserver('CSTStudio.Application'); % Opens CST
CST.FileNew(); % Creates a new file
MWS = CST.Active3D; % Set focus to the new file
MWS.invoke("AddToHistory","Test",""); % Append to history list
这是我试图用来控制COM对象的C代码
cst_design_environmentLib.IApplication CST = new cst_design_environmentLib.Application(); // Opens CST
CST.FileNew(); // Creates a new file
dynamic MWS = CST.Active3D(); // Set focus to the new file
MWS.AddToHistory("Test", ""); // Doesn't work, produces an error
直到我尝试运行方法AddToHistory
,该方法失败并出现以下错误:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.__ComObject' does not contain a definition for 'AddToHistory'
我知道方法AddToHistory
是存在的,因为1)我通过MATLAB访问过它,2)它在这里。那么为什么它不通过C#运行呢?因为MWS
对象是动态类型的,所以我知道该方法不会在编译时找到,但应该在运行时找到,对吗?我已经调试并检查了对象的类型,CST
和MWS
都是系统。当我检查这些对象的动态视图时,它说“无法找到关于这个对象的更多信息”,所以它似乎找不到任何方法
另外,CST
的类型是类型库CST\u design\u environmentLib
的一部分,因此FileNew()
等方法是由intellisense预测的,但我不相信MWS
的类型是类型库的一部分
在此方面的任何帮助都将不胜感激。我通过使用InvokeMember
实现了以下功能:
// Create an instance of CST
Type t = Type.GetTypeFromProgID("CSTStudio.Application");
object CST = Activator.CreateInstance(t);
// Create a new file
t.InvokeMember("FileNew", BindingFlags.InvokeMethod, null, CST, null);
// Set focus to the new file
object MWS = t.InvokeMember("Active3D", BindingFlags.InvokeMethod, null, CST, null);
// Add something to the model history
t.InvokeMember("AddToHistory", BindingFlags.InvokeMethod, null, MWS, new string[] {"Test", ""});
这是可行的,但如果有人能解释为什么我的原始代码不起作用,那就太好了。如评论中所述,您可以使用C#4功能动态
。它是为后期装订而设计的。我的答案是以你的为基础的,但我把它整理好了
MSDN必须在dynamic
C#团队在C#4版本中特别针对的COM互操作场景是针对Microsoft Office应用程序(如Word和Excel)编程的。其目的是使这项任务在C#中像在Visual Basic中一样简单自然。这也是VisualBasic和C#co-evolution策略的一部分,这两种语言都以功能对等为目标,并相互借鉴最佳和最有效的解决方案
这是可行的,但如果有人能解释为什么我的原始代码不起作用,那就太好了
正如我在上述评论中提到的:
我注意到您正在使用互操作包装器,直到CST.Active3D()为止,然后您将下拉到dynamic,这向我建议AddToHistory不可用,因为您使用的是旧的/错误的COM引用。第一个示例是如何创建独立于版本的CSTStudio.Application。也许可以通过Activator.CreateInstance尝试类似的方法
然后将dynamic与Type.InvokeMethod
混合使用。虽然还可以,但是当动态
可以按照上面的方法节省时间时,它有点冗长
作品:
如果我将最后两行代码更改为以下代码,它将不再工作dynamic MWS=t.InvokeMember(“Active3D”,BindingFlags.InvokeMethod,null,CST,null);MWS.AddToHistory(“Test”和“);。它说找不到方法
这是因为您正在使用Type
调用这些方法。我怀疑它没有使用后期绑定,因此为什么动态
。对于行Activator.CreateInstance(t)
,应该只使用变量t
CST
和MWS
应该是dynamic
我注意到您使用的是interop包装,一直到CST.Active3D()
为止,然后您下拉到dynamic
,这向我建议AddToHistory
不可用,因为您使用的是旧的/错误的COM引用。第一个示例是如何创建独立于版本的CSTStudio.Application
。也许可以通过Activator.CreateInstance
尝试一件事是的,但是你改变了两件事,你只需要使用Activator.CreateInstance
。您不必删除dynamic
——这就是C#4+中的功能。很高兴你还是这么做的。看起来您以前使用的是旧的COM引用/包装器如果我将最后两行代码更改为以下代码,它将不再工作dynamic MWS=t.InvokeMember(“Active3D”,BindingFlags.InvokeMethod,null,CST,null);MWS.AddToHistory(“测试”和“)代码>。它说它找不到方法。这是因为您正在使用Type
调用方法。您应该只对行Activator.CreateInstance(t)
使用变量t
,而不在其他地方使用CST
应该是动态的
。感谢您迄今为止的帮助,我非常感谢。我试着运行您在此评论中发布的代码,它运行正常,直到行CST.FileNew()
出现错误,“System.\uu ComObject”不包含“FileNew”的定义。
。到目前为止,我让它工作的唯一方法是调用所有东西,dynamic
从未工作过。我怀疑我正在使用的COM.dll是旧的,不符合当前的标准。@PaperBee这很好,先生,很乐意帮助。COM有时可能是个讨厌的恶魔;)
// Create an instance of CST
Type t = Type.GetTypeFromProgID("CSTStudio.Application");
dynamic CST = Activator.CreateInstance(t);
// Create a new file
CST.FileNew();
// Set focus to the new file
dynamic MWS = CST.Active3D();
// Add something to the model history
MWS.AddToHistory (new string[] {"Test", ""});