2

I am working on a application which needs to communicate via COM interface with multiple CAD applications (not in the same time). I want to have nice and reusable code, but I came across problems with type casting of COM objects when I made generic application handle getter method.

What I tried so far:

  1. This is the attempt I would like the most if it worked.

    public static TCadAppType CadApp<TCadAppType>()
    {
        dynamic cadApp = default(TCadAppType);
    
        //Here under Dynamic View/Message there is already an error
        //  Message = "Element not found. (Exception from HRESULT: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))"
        // cadVersion.Value evaluates to "SldWorks.Application"
        cadApp = (TCadAppType)Marshal.GetActiveObject(cadVersion.Value);
    
        //Following 2 lines of code are for testing purposes only, i am testing with Solidworks API 
        AssemblyDoc Assembly;
    
        //The exception is thrown when I try to access some method from the Solidworks API 
        Assembly = (AssemblyDoc)cadApp.OpenDoc6("some parametras...");
    
    }
    
  2. Attempt using Convert class

    // Another attempt using  Convert class
    public static TCadAppType CadApp<TCadAppType>()
    {
        dynamic cadApp = default(TCadAppType);
        // cadVersion.Value evaluates to "SldWorks.Application"
        cadApp = Marshal.GetActiveObject(cadVersion.Value);
    
    
        cadApp = Convert.ChangeType(cadApp, typeof(SldWorks.SldWorks));
        // Exception is thrown with the following message:
        // Message = "Object must implement IConvertible."
    }
    

I really thought that I am on the right track, since there is an article on Microsoft Docs website explaining how dynamic can help you with com interopt: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop

Any ideas how I can do this runtime casting a keep my code as reusable as possible?

My software setup:

  • Win 10
  • Project is targeted for .NET 4.7.2
  • First Tests are with Solidworks 2019
8
  • 1
    What exactly is TCadAppType? COM object has to have that interface implemented if you want to use it. You cannot cast it to some other C# object. Commented Dec 27, 2018 at 2:20
  • TCadType is just a generic type for this generic method. Later on I can call the method for example SldWorks.Sldworks CadApp<SldWorks.Sldworks >() Commented Dec 27, 2018 at 8:22
  • So you want to cast "SldWorks.Application" to "SldWorkd.SldWorks" ? I am getting some generic confusion here but just cannot put finger on it. Commented Dec 27, 2018 at 18:33
  • Well, not exactly... "SldWorks.Application" is just a string, which represents ProgID. Return value of Marshal.GetActiveObject is an object that you can cast to any COM interface that it supports. For my case, the interface is SldWorks.SldWorks. More on this on the following link: Marshal.GetActiveObject Commented Dec 27, 2018 at 20:52
  • Maybe building thin wrapper around dynamic object would be a better approach. Commented Dec 27, 2018 at 23:55

1 Answer 1

0

Turns out that the my coding attempt 1 was valid c# code indeed. I tried it using with Autodesk Inventor, and it works.

So the only thing left for me is to conclude that this is some bug from Solidworks and their COM interfacing.

Thank you Optional Option for your interest in the topic.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.