You can customize Excel UI by creating your own Ribbons and Custom Task Panes. Normally these are implemented as COM AddIns, require registration etc.

FCell makes it much easier: all you have to do is create a class which extends XlRibbon, defined in FCell runtime.

FCell will automatically take care of all the COM requirements.

Create a simple ribbon and custom task pane

We wil create a class MyRibbon which inherits from XlRibbon.

Ribbon UI is defined as xml. You can find full specification here

We will return our ribbon xml by overriding GetCustomUI method in MyRibbon.

Any ribbon event handlers, e.g. button click, can be implemented as instance methods in MyRibbon

Custom Task Pane can be implemented as a System.Windows.Forms.UserControl. We then override OnCTPFactoryAvailable and call CreateCustomTaskPane

F# Copy imageCopy
namespace Test
open System
open FCell.ManagedXll
open System.Runtime.InteropServices
open System.Windows.Forms
open System.Reflection
open FCell.Ribbon

//force a new assembly version on each build to allow reloading the ribbon customization
[<assembly: AssemblyVersion("1.0.0.*")>]
do()

//implement your Custom Ribbon as Windows UserControl:
[<ComVisible(true)>]
type MyTaskPane() =
    inherit UserControl()

[<ComVisible(true)>]
type MyRibbon() =
    inherit XlRibbon()

    //define your Ribbon customization as xml, see Office documentation for details
    override this.GetCustomUI(ribbonID : string) =
        @"
        <customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui' onLoad='OnLoad' loadImage='GetImage'>
            <ribbon>
            <tabs>
                <tab id='FSTabId' label='MyMenu'>
                <group id='FSGroupId' label='FSGroup'>
                    <button id='FSButtonId' imageMso='PageMenu' label='MyButton'
                    size='large' onAction='OnButtonClick' />
                </group>
                </tab>
            </tabs>
            </ribbon>
        </customUI>"

    //handle MyButton click event
    member this.OnButtonClick(control : IRibbonControl) =
        MessageBox.Show("Hello from MyButton") |> ignore

    //create Custom Task Pane
    override this.OnCTPFactoryAvailable() =
        let ctp = this.CreateCustomTaskPane(typeof<MyTaskPane>, "MyTaskPane")
        ctp.Visible <- true
C# Copy imageCopy
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using FCell.ManagedXll;
using FCell.Ribbon;

[assembly: AssemblyVersion("1.0.0.*")]//force a new assembly version on each build to allow reloading the ribbon customization 
namespace CSharpRibbon
{
    //implement Custom Task Pane
    [ComVisible(true)]
    public class MyTaskPane : UserControl
    {
    }

    [ComVisible(true)]
    public class MyRibbon : XlRibbon
    {
        public override string GetCustomUI(string RibbonID)
        {
            var xml = @"
                        <customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui' onLoad='OnLoad' loadImage='GetImage'>
                        <ribbon>
                        <tabs>
                            <tab id='MyTabId' label='MyMenu'>
                            <group id='MyGroupId' label='MyGroup'>
                                <button id='MyButtonId' imageMso='PageMenu' label='MyButton'
                                size='large' onAction='OnButtonClick' />
                            </group>
                            </tab>
                        </tabs>
                        </ribbon>
                        </customUI>";
            return xml;
        }

        //create custom task pane
        public override void OnCTPFactoryAvailable()
        {
            var ctp = this.CreateCustomTaskPane(typeof(MyTaskPane), "MyTaskPane");
            ctp.Visible = true;
        }

        //handle MyButton click event
        public void OnButtonClick(IRibbonControl control)
        {
            MessageBox.Show("Hello from MyButton");
        }
    }
}
Visual Basic Copy imageCopy
Imports FCell.ManagedXll
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports FCell.Ribbon
Imports System.Xml.Linq

'force a new assembly version on each build to allow reloading the ribbon customization 
<assembly: AssemblyVersion("1.0.0.*")>

'implement Custom Task Pane
<ComVisible(True)>
Public Class MyTaskPane
    Inherits UserControl
End Class

<ComVisible(True)>
Public Class MyRibbon
    Inherits XlRibbon

    'define ribbon xml
    Overrides Function GetCustomUI(ByVal ribbonID As String) As String
        Dim res As XElement
        res =    <customUI xmlns='http://schemas.microsoft.com/office/2006/01/customui' onLoad='OnLoad' loadImage='GetImage'>
                      <ribbon>
                          <tabs>
                              <tab id='VBTabId' label='MyMenu'>
                                  <group id='VBGroupId' label='MyVBGroup'>
                                      <button id='VBButtonId' imageMso='PageMenu' label='MyButton'
                                          size='large' onAction='OnButtonClick'/>
                                  </group>
                              </tab>
                          </tabs>
                      </ribbon>
                  </customUI>
        Return res.ToString()
    End Function

    'handle MyButton click event
    Public Sub OnButtonClick(ByVal control As IRibbonControl)
        MessageBox.Show("Hello from MyButton")
    End Sub

    'create custom task pane
    Overrides Sub OnCTPFactoryAvailable()
        Dim ctp = Me.CreateCustomTaskPane(GetType(MyTaskPane), "MyTaskPane")
        ctp.Visible = True
    End Sub

End Class