Creating an instance of a COM interop class

2019-04-09 20:11发布

问题:

I am trying to open CorelDRAW from within my program using C#. So far I have been able to do so by referencing the appropriate com library and calling

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

However, I would like my program to work with any version of CorelDRAW that supports interop. I am attempting to use reflection to load the interop library at runtime, where the specific dll can be chosen for the correct version. From looking around I have tried the following.

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);
}

The program fails at u.CreateInstance... fails because CorelDRAW.Application is an interface, not a class. I have also tried replacing CorelDRAW.Application with CorelDRAW.ApplicationClass as that is available when I browse through Interop.CorelDRAW as a resource, but then u.getType... fails.

How can I get this to work? Thank you!

回答1:

You can create instances of registered ActiveX objects using following construct:

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

Then you have 3 options, on how to work with returned object.

  1. Casting returned object to real CorelDRAW.Application interface, but for this you need to reference some CorelDraw library which contains it, and probably this will produce versioning problems.

  2. Reflection, which you mention in your question.

  3. Use dynamic keyword, so you can call existing methods and properties just like it was a real CorelDraw class/interface.

    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);

this is gonna work