【问题标题】:CreateObject C#创建对象 C#
【发布时间】:2015-07-03 21:25:06
【问题描述】:

我已经有一个本机代码 COM 对象,并且正在尝试从 C# 实例化它。 Com 在 DCOM 组件和注册表中注册。

这是我尝试做的:

public static void Main(string[] args)
{
    Type t = Type.GetTypeFromProgID("CaseConsole.Application");

    dynamic app = Activator.CreateInstance(t);
    dynamic c = app.Case;

    c.OpenCase("17-16", 0);
}

如果我尝试实例化 com 类型,我会得到:

NotImplementedException

execption 在以下行抛出:

dynamic c = app.Case;

当我在这一行设置断点时,我查看了“app”并且错误已经存在

我查看了 Type t,它显示:IsCOMObject = true

作为 VBS 效果很好:

Dim App
Dim c

Set App = CreateObject ("CaseConsole.Application")
Set c = App.Case

c.OpenCase "17-16", 0

像 VB.net 一样工作

Sub Main()
    Dim App
    Dim c

    App = CreateObject("CaseConsole.Application")
    c = App.Case

    c.OpenCase("17-16", 0)
End Sub

但不是在 C# 中

对于 C# 示例,我查看了来自

的源代码

http://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE

https://msdn.microsoft.com/en-us/library/aa645736%28v=vs.71%29.aspx

Equivalent code of CreateObject in C#

我的猜测是我必须使用 InvokeMember 或安全性来调用方法...

请您帮助使 c# 示例正常工作吗?

更新将大小写重命名为 c 但这不是问题。

【问题讨论】:

  • dynamic没问题?

标签: c# com createobject


【解决方案1】:

非常感谢 Sami Kuhmonen,解决方案是:

object c = t.InvokeMember("Case", BindingFlags.GetProperty, null, app, null);
t.InvokeMember("OpenCase", BindingFlags.InvokeMethod, null, c, new object[] { "17-16", 0 });

所以我没有意识到“Case”是一个属性。

已解决

【讨论】:

    【解决方案2】:

    您的 C# 程序与 VBS 和 VB.NET 程序略有不同。运行此代码的线程的单元状态是不同的。异常来自代理,应解释为“不支持从工作线程运行此代码”。做得很好。修复:

    [STAThread]
    public static void Main(string[] args)
    {
       // etc..
    }
    

    注意添加的 [STAThread] 属性。这样做在技术上是不正确的,控制台模式应用程序没有为单线程 COM 对象提供正确类型的运行时环境,但如果 VB.NET 应用程序正常工作,那么您就不用担心了。如果您注意到死锁,那么您就会知道要寻找什么。当您通过 InvokeMember 使用后期绑定时它会起作用,因为它使用 IDispatch 并且它具有不同的代理。

    【讨论】:

      猜你喜欢
      • 2011-02-14
      • 2021-12-30
      • 2021-10-21
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多