Skip to content

Docs: Custom Task Panes section omits the .NET 6+ COM default-interface requirement #17

Description

@webdjoe

Summary

src/pages/reference-various.mdCustom Task Panes documents the CTP API but not the COM attribution a UserControl needs on .NET 6+. Without it, CustomTaskPaneFactory.CreateCustomTaskPane fails with a bare E_FAIL (0x80004005) and no diagnostic text.

This is already known — you answered it in issue #558 and in the group thread CustomTaskPaneFactory.CreateCustomTaskPane throws 'Unable to create specified ActiveX control':

You now need an explicit 'default interface' for your type - this will cause the class to implement IDispatch (if it is ComVisible).

The reference page doesn't carry that, so it's still reachable by reading the docs alone.

What I measured

Standalone add-in, no other dependency, ExcelDna.AddIn 1.9.0, SDK 10.0.400, Excel 16.0.20326.20112 x64 Click-to-Run Current Channel, Windows 11 25H2 26200.9168, not elevated, Defender only, Trust Center at defaults.

Control under test:

[ComVisible(true)]
public sealed class FixedLabelControl : UserControl
{
    public FixedLabelControl() => Controls.Add(new Label { Text = "Repro Pane", AutoSize = true });
}
Target Runtime Result
net10.0-windows 10.0.11 COMException, HRESULT -2147467259 (0x80004005)
net7.0-windows 7.0.7 COMException, HRESULT -2147467259 (0x80004005)

Byte-identical source both times; only the TFM differed. Adding the documented attribution and changing nothing else:

[ComVisible(true)]
[Guid("...")]
public interface IFixedLabelControl { }

[ComVisible(true)]
[Guid("...")]
[ComDefaultInterface(typeof(IFixedLabelControl))]
public sealed class FixedLabelControl : UserControl, IFixedLabelControl { ... }

net10.0-windows then completed the full lifecycle — create, show, hide, delete, dispose — with no HRESULT.

Because the requirement splits .NET Framework from .NET Core rather than one .NET version from another, a net7-vs-net10 comparison can't discriminate it: both fail identically. That cost me a fair amount of bisecting before I found #558, which is really the motivation for this request.

Suggested addition

After the CreateCustomTaskPane example in the Custom Task Panes section:

.NET 6 and later: the control needs an explicit COM default interface. .NET Framework generated a class interface automatically, so a [ComVisible(true)] UserControl had a usable IDispatch; .NET Core and later do not, and CreateCustomTaskPane then fails with E_FAIL / "Unable to create specified ActiveX control".

public interface IMyUserControl { }

[ComVisible(true)]
[Guid("....")]
[ComDefaultInterface(typeof(IMyUserControl))]
public class MyUserControl : UserControl, IMyUserControl { }

Happy to open a PR against src/pages/reference-various.md if that's easier.

Separately, if it's ever cheap to do

ExcelCustomTaskPane.CreateCustomTaskPane already logs a helpful message for the UnauthorizedAccessException registry case. A comparable hint when ICTPFactory.CreateCTP throws E_FAIL — pointing at the default-interface requirement — would make this self-diagnosing. Entirely optional; the docs change is the ask.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions