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.