Dynamically loading a ribbon

185 views
Skip to first unread message

Antonio Nakić-Alfirević

unread,
May 3, 2021, 9:44:15 AM5/3/21
to Excel-DNA
I'm trying to register a ribbon from a dynamically loaded dll. 

To try things out, I've defined the simplest possible ribbon class:

[ComVisible(true)]
public class TestDynamicRibbon : ExcelRibbon
{
    public override string GetCustomUI(string RibbonID)
    {
        Trace.Write("It's called!");
        return base.GetCustomUI(RibbonID);
    }
}

If I define this class inside my ExcelDNA entry point project, the GetCustomUI method is called just fine. It is called indirectly from the ExcelComAddIn.LoadComAddIn() method, through a native method call.

However, in the situation I'm interested in, the TestDynamicRibbon class  is not part of the main project. Rather, it is inside a dll that is dynamically loaded at some later point, while Excel is running. 
 
I figured I could just call ExcelComAddIn.LoadComAddIn(testRibbonInstance) but this does not result in GetCustomUI being called. Am I missing some prerequisite step for this?

Govert van Drimmelen

unread,
May 3, 2021, 10:03:34 AM5/3/21
to exce...@googlegroups.com
----------
Excel-DNA is now registered on GitHub Sponsors.
Please sign up as a sponsor to help fund future development.
----------

Hi Antonio,

My first thought is also that it should work. The call to GetCustomUI happens from Excel because it sees that the class implements the IRibbonExtensibility interface.
You might override other methods from ExcelComAddIn like OnConnection, to see if the COM add-in is loaded at all.
I'm guessing it is not, and something goes wrong with the COM registration.
Maybe your class is not public enough, misses some attributes or something similar.

Here I tried to see how one could decouple the registration from what Excel-DNA does automatically.
I had to jump through some hoops to make a ribbon class that Excel-DNA will not pick up and register automatically (which happens to any ExcelRibbon-derived class).
So I kind of re-implement the ribbon part here, on top of the ExcelComAddIn base class, and then load that at runtime.
I'm not sure that helps you, since your problem is likely in the COM add-in loading, but it gives a bit more to experiment with.

-Govert



--
You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/exceldna/a0f788c6-cd42-492b-b15c-05e4e0125ba0n%40googlegroups.com.

Antonio Nakić-Alfirević

unread,
May 3, 2021, 10:20:14 AM5/3/21
to exce...@googlegroups.com
Yes, that's it, it was not public enough!

While I was testing things out, I had made the ribbon class internal and changed the code in AssemblyLoader.GetExcelAddIns to only look at public types so it wouldn't pick up my ribbon test class.

I now made it public and explicitly filtered it out by name in the  AssemblyLoader.GetExcelAddIns (just to try it out) and now GetCustomUI gets called from ExcelComAddIn.LoadComAddIn and my custom ribbon appears in Excel!

Thanks, Govert!

Antonio Nakić-Alfirević

unread,
May 5, 2021, 10:33:54 AM5/5/21
to exce...@googlegroups.com
Additional question for you, Govert: Is there a way to unregister the ribbon instance? 

I'd like to be able to remove the dynamically added ribbon without the user having to restart Excel.

I'm basically looking for an opposite operation to ExcelComAddIn.LoadComAddIn. Is there such a thing?

Govert van Drimmelen

unread,
May 5, 2021, 11:00:31 AM5/5/21
to exce...@googlegroups.com
Hi Antonio,

You can go through the Application.ComAddIns collection and check the names.
When you get the right one, call .Connect = false and it should unload.

-Govert


Antonio Nakić-Alfirević

unread,
May 5, 2021, 11:35:51 AM5/5/21
to exce...@googlegroups.com
Yep, that works. 

I can store the existing comaddins in a variable, register my new ribbon addin and read the ComAddins collection again to find the new instance (so I don't have to rely on the description). 

Thanks, Govert!

Reply all
Reply to author
Forward
0 new messages