IPictureDisp and CommandManager.ControlDefinitions.AddButtonDefinition issues

IPictureDisp and CommandManager.ControlDefinitions.AddButtonDefinition issues

mike_ponti
Enthusiast Enthusiast
1,239 Views
7 Replies
Message 1 of 8

IPictureDisp and CommandManager.ControlDefinitions.AddButtonDefinition issues

mike_ponti
Enthusiast
Enthusiast

Hello all, hoping someone has run into this or something similar before. I have been working on an addin, off and on for the last year or so. Yesterday afternoon, everything was fine. I was building, deploying and debugging and everything was fine.

 

Then, suddenly, none of my UI was visible. I dug in and found out that there was an exception being thrown in the below code.

    ButtonDefinition = commandManager.ControlDefinitions.AddButtonDefinition(
        DisplayName,
        InternalName,
        Classification,
        ClientId,
        Description,
        ToolTipText,
        standardIconPict,
        largeIconPict,
        ButtonDisplay
    );
    // EXCEPTION THROWN ON ABOVE STATEMENT
    // System.Runtime.InteropServices.COMException (0x8000FFFF): Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

 

The above code is called from a base class for ButtonCommands so it is used in a lot of places, not just this project. Most of the items are just properties, the exception being the IPictureDisp parameters.

 

I suspected that these were the issue so changed the values for the icons to null and now the buttons loaded, but of course had no icons for the buttons.

 

My normal procedure is to store the png's for the buttons as embedded resources. The base class loads the embedded resource in as a bitmap object and then passes it to the converter to get the IPictureDisp.

 

The converter is probably pretty familiar as it came from a blog post from ex-ADN Phillipe L which is below.

public class PngConverterOle
{
    [DllImport("OleAut32.dll", EntryPoint = "OleCreatePictureIndirect", ExactSpelling = true, PreserveSig = false)]
    private static extern stdole.IPictureDisp OleCreatePictureIndirect([MarshalAs(UnmanagedType.AsAny)] object picdesc, ref Guid iid, [MarshalAs(UnmanagedType.Bool)] bool fOwn);
    
    static Guid iPictureDispGuid = typeof(stdole.IPictureDisp).GUID;

    private static class PICTDESC
    {
        //Picture Types
        public const short PICTYPE_UNINITIALIZED = -1;
        public const short PICTYPE_NONE = 0;
        public const short PICTYPE_BITMAP = 1;
        public const short PICTYPE_METAFILE = 2;
        public const short PICTYPE_ICON = 3;
        public const short PICTYPE_ENHMETAFILE = 4;

        [StructLayout(LayoutKind.Sequential)]
        public class Bitmap
        {
            internal int cbSizeOfStruct = Marshal.SizeOf(typeof(PICTDESC.Bitmap));
            internal int picType = PICTDESC.PICTYPE_BITMAP;
            internal IntPtr hbitmap = IntPtr.Zero;
            internal IntPtr hpal = IntPtr.Zero;
            internal int unused;

            internal Bitmap(System.Drawing.Bitmap bitmap)
            {
                this.hbitmap = bitmap.GetHbitmap();
            }
        }
    }

    public static stdole.IPictureDisp ToIPictureDisp(System.Drawing.Bitmap bmp)
    {
        PICTDESC.Bitmap pictBmp = new PICTDESC.Bitmap(bmp);
        var result = PngConverterOle.OleCreatePictureIndirect(pictBmp, ref iPictureDispGuid, false);
        return result;
    }
}

 

The crazy thing is that this code hasn't changed since summer 2021 and the icons haven't changed since before that.

Things I have tried:
- updated Inventor
- tried different versions of Autodesk.Inventor.interop
- tried using AxHost to do the conversion (doesn't work in MTA thread apartment)
- verified that png's are loading and correct size
- tried Inventor 2019, 2021 and 2022

- rebooted (desperation)

 

I am going to try and uninstall and re-install the different Inventor versions, but in the meantime, wanted to get this out there in case someone has see this before.

 

Thanks all!

 

 

 

 

 

 

0 Likes
Accepted solutions (1)
1,240 Views
7 Replies
Replies (7)
Message 2 of 8

bradeneuropeArthur
Mentor
Mentor

Try a different framework too!

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 3 of 8

mike_ponti
Enthusiast
Enthusiast

Thank you, will try and update below!

0 Likes
Message 4 of 8

mike_ponti
Enthusiast
Enthusiast

I finally finished the uninstalls and updates. Uninstalled 2019, 2021 and 2022 and installed with latest updates 2020, 2021 and 2022. No change in the behavior. Still throws on the AddButtonDefinition with the same catastrophic failure. I was unable to knock it back to an earlier framework as it relies on a library that was built against 4.8.

 

I think at this point, I am going to try and create a brand new add in, no dependencies except for my own inventor helpers library and see what happens.

 

Thank you for your suggestion @bradeneuropeArthur !

Message 5 of 8

bradeneuropeArthur
Mentor
Mentor

Compiling 64 or 32 bit version?

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 6 of 8

mike_ponti
Enthusiast
Enthusiast

@bradeneuropeArthur , I am compiling "Any CPU". Hasn't been a problem in the past.

 

I created a new addin and ran it and it setup without any problem. One very interesting observation ... I originally went to using the DllImport of "OleCreatePictureIndirect" because my years of using the AxHost control to do the conversion didn't work in an "Multi-Thread-Apartment" (MTA) process.

 

I had a "Debug.Writeline" statement hanging around that showed what "Thread Model" the addin was running in. Here we can see that when my new test addin is loading, it runs under an STA thread model.

thread-test-addin.jpg

 

And now we have the problem addin which shows that it is running under MTA:

thread-problem-addin.jpg

 

I am no COM expert, so just theorizing here. I am guessing that one of my other dependencies is causing the addin to load under an MTA model. How that happens is ... (more than a little) unclear to me.

 

I guess the next step is to try and isolate out these dependencies, my first choice is "MaterialDesignsThemes.Wpf" that I use to help me out with some presentation stuff. It is the first time I have tried using it and had never had any of these issues before.

 

Appreciate all that are following along on this!

 

 

 

0 Likes
Message 7 of 8

mike_ponti
Enthusiast
Enthusiast

I guess this is turning into a bit of a live blog or something....

 

My hunch about the STA vs MTA seems to be correct. I have a function in my StandardAddinServer class that checks the app store entitlement endpoint for subscription status. Something in there changes things from STA to MTA. If I comment out the entitlement check, it never switches to MTA and the UI with icons is created.

 

The entitlement check uses async functions, is this what switches to MTA? Next check will be to make the entitlement check synchronous. Or I can move it into the command execution directly. Making it synchronous will be probably the easiest thing so will try that first.

 

to be continued ...

0 Likes
Message 8 of 8

mike_ponti
Enthusiast
Enthusiast
Accepted solution

As usual ... it is all my fault.

 

I put an async function indirectly into the "StandardAddinServer.Activate". On reflection, can see that wasn't a great idea, I was more focused on getting entitlement figured out and passed to the actual commands.

 

The reason why it worked before is because I had stubbed in the entitlement check and when I put the real one in I just automatically used the "HttpClient" which is completely async. If you want non-async HTTP rest calls you need to use HttpWebRequest, HttpWebResponse instead.

 

Thanks all and especially @bradeneuropeArthur for your suggestions.