COM returns a type that does not implement any interface

I need to automate some tasks in Adobe InDesign CS3 from a .NET 4.0 application. I added a link to the InDesign type library using the Add Link dialog in Visual Studio. It generates an interop assembly that correctly includes all the interfaces and types declared in the type library. I did not install any Adobe SDKs because the type library was available in Visual Studio without installing anything other than Adobe InDesign CS3.

The interesting types in the interop assembly for me right now are the _Application and Application interfaces, and the ApplicationClass class. Here is a definition of them, so you can see the relationship between them:

 public interface _Application { // Lots of properties and methods } public interface Application : _Application { // Empty } public class ApplicationClass : _Application, Application { // The same properties and methods as declared in _Application } 

I am trying to instantiate a COM object as follows:

 Type oType = Type.GetTypeFromProgID("InDesign.Application.CS3"); if (oType != null) { object instance = Activator.CreateInstance(oType); } 

This code succeeds. I get an instance, but of type __ComObject . From what I know, this is absolutely normal.

Now where the fun begins. For this instance to be useful to me, I have to bring it to the correct interface. From other examples on the web and from the documentation available here , I see that I have to pass it to the Application interface. But if I do, I get a nasty InvalidCastException saying that the System.__ComObject does not support this interface. I get the same exception if I try to apply it to ApplicationClass or the _Application interface.

I thought I might have used the wrong interface, so I tried to implement the utility function mentioned here . This function goes through all the interfaces declared in the interop assembly and requests the IUnknown interface if it implements the interface.

When I use this function, it returns null, which means that the instance returned from CreateInstance does not support any of the interfaces in the interop assembly. Of course, this cannot be right !?

However, if I check the instance variable using Visual Studio Debugger, there is something called "Dynamic View". If I expand it, it lists all the properties of the object, and all the properties correspond to the properties of the ApplicationClass and _Application . So I tried using Type.InvokeMember and this works:

 oType.InvokeMember("DoScript", BindingFlags.InvokeMethod, null, instance, oArguments, CultureInfo.InvariantCulture); 

It really works, but it would be extremely cumbersome to interact with a COM object like this, and I need to work a lot with a COM object, so this is not very convenient. I suppose I could make a wrapper for COM objects, but this view defeats the purpose of the interop assembly, and I don't want to create more than 700 wrapper classes.

I searched alot and I found tutorials and examples of using the InDesign COM object, but they all just returned the instance returned to the application interface, but as explained, this does not work in my case.

I also tried the following code instead of the code above:

 InDesign.Application app = new InDesign.Application(); app.Activate(); 

The first line succeeds, and I get an instance of ApplicationClass , but when it tries to execute the second line, I get an InvalidCastException, stating that ApplicationClass cannot be converted to the _Application interface.

I really cornered here, and am not sure what to try next. I really hope someone more experienced with COM and .NET has an idea of ​​what I might be doing wrong.

Thanks in advance, and sorry for such a long post.

+4
source share
2 answers

You must use Runtime Callable Wrapper

You need this

Try the following:

  Type oType = Type.GetTypeFromProgID("InDesign.Application.CS3"); if (oType != null) { object instance = Activator.CreateInstance(oType);// or any other way you can get it Application app = (Application)System.Runtime.InteropServices.Marshal.CreateWrapperOfType(instance, typeof(ApplicationClass)); } 
+2
source

I have not worked with COM recently, but as far as I remember (and understood your problem), you cannot use ComObject as follows:

  Application app = (Application)comObject; 

but you should use it as an operator:

  Application = comObject as Application; 
0
source

All Articles