【问题标题】:Creating an instance of a COM interop class创建 COM 互操作类的实例
【发布时间】:2012-10-07 05:25:28
【问题描述】:

我正在尝试使用 C# 从我的程序中打开 CorelDRAW。到目前为止,我已经能够通过引用适当的 com 库并调用来做到这一点

CorelDRAW.Application draw = new CorelDRAW.Application();
draw.Visible = true; 

但是,我希望我的程序可以与任何支持互操作的 CorelDRAW 版本一起使用。我正在尝试使用反射在运行时加载互操作库,其中可以为正确的版本选择特定的 dll。环顾四周,我尝试了以下方法。

string path = "Interop.CorelDRAW.dll";
Assembly u = Assembly.LoadFile(path);
Type testType = u.GetType("CorelDRAW.Application");

if (testType != null)
{
    object draw = u.CreateInstance("CorelDRAW.Application");

    FieldInfo fi = testType.GetField("Visible");
    fi.SetValue(draw, true);
}

程序在u.CreateInstance... 失败,因为CorelDRAW.Application 是一个接口,而不是一个类。我还尝试将CorelDRAW.Application 替换为CorelDRAW.ApplicationClass,因为当我浏览Interop.CorelDRAW 作为资源时可以使用,但随后u.getType... 失败。

我怎样才能让它工作?谢谢!

【问题讨论】:

  • 我已经在某种程度上得到了这个工作。我在我的 C# 解决方案中创建了 5 个附加项目,每个项目都包含对特定版本 Corel 的引用。然后该项目有一个返回我的 CorelDRAW.Application 对象的函数。然后我可以在主程序中对该对象使用反射。不是最干净的,但到目前为止已经足够了。

标签: c# reflection .net-assembly com-interop coreldraw


【解决方案1】:

您可以使用以下构造创建已注册 ActiveX 对象的实例:

Type type = Type.GetTypeFromProgID("CorelDRAW.Application", true);
object vc = Activator.CreateInstance(type);

那么你有 3 个选项,关于如何使用返回的对象。

  1. 将返回的对象转换为真实的 CorelDRAW.Application 接口,但为此您需要引用一些包含它的 CorelDraw 库,这可能会产生版本控制问题。

  2. 您在问题中提到的反思。

  3. 使用 dynamic 关键字,因此您可以像调用真正的 CorelDraw 类/接口一样调用现有方法和属性。

    Type type = Type.GetTypeFromProgID("CorelDRAW.Application", true);
    dynamic vc = (dynamic)Activator.CreateInstance(type);
    vc.Visible = true;
    

【讨论】:

    【解决方案2】:
      System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(fullPath);
      dynamic app = assembly.CreateInstance("CorelDRAW.ApplicationClass", true);
    

    这会奏效

    【讨论】:

      猜你喜欢
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 2012-02-27
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      相关资源
      最近更新 更多