BluePointLilac/ContextMenuManager · critical · COMException

Failed to create ShellLink object.

Error message

Failed to create ShellLink object.

What it means

The ShellLink constructor instantiates the COM class CShellLink (which implements IShellLinkW, the Windows shell shortcut interfaces). If the COM activation fails — because shell32 is not registered, COM is uninitialized, or the process lacks shell access — the original exception is swallowed and re-thrown as a COMException with a generic message. This masks the root cause, making diagnosis harder.

Source

Thrown at ContextMenuManager/BluePointLilac.Methods/ShellLink.cs:274

        {
            get
            {
                LinkDataList.GetFlags(out ShellLinkDataFlags flags);
                return (flags & ShellLinkDataFlags.RunasUser) == ShellLinkDataFlags.RunasUser;
            }
            set
            {
                LinkDataList.GetFlags(out ShellLinkDataFlags flags);
                if(value) flags |= ShellLinkDataFlags.RunasUser;
                else flags &= ~ShellLinkDataFlags.RunasUser;
                LinkDataList.SetFlags(flags);
            }
        }

        public ShellLink(string lnkPath = null)
        {
            try { shellLinkW = (IShellLinkW)new CShellLink(); }
            catch { throw new COMException("Failed to create ShellLink object."); }
            Load(lnkPath);
        }

        ~ShellLink() { Dispose(false); }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(shellLinkW == null) return;
            Marshal.FinalReleaseComObject(shellLinkW);
            shellLinkW = null;
        }

View on GitHub (pinned to 55507155dd)

Solutions

  1. Ensure the application runs on Windows with shell32 registered (guard with RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  2. Ensure the instantiating thread is STA: apply [STAThread] to Main, or call thread.SetApartmentState(ApartmentState.STA) before thread.Start()
  3. Verify the process has shell COM access (not running in an AppContainer or sandbox)
  4. If publishing with trimming, disable COM interop trimming or add a runtime directive for the ShellLink types

Example fix

// before
var link = new ShellLink(shortcutPath);

// after
if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    throw new PlatformNotSupportedException("ShellLink requires Windows.");

var link = new ShellLink(shortcutPath);
Defensive patterns

Strategy: try-catch

Validate before calling

static bool CanCreateShellLink()
{
    return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
        && Type.GetTypeFromCLSID(typeof(CShellLink).GUID) != null;
}

if(!CanCreateShellLink())
    throw new PlatformNotSupportedException(
        "ShellLink COM object is not available on this platform.");

Try / catch

ShellLink link = null;
try
{
    link = new ShellLink(lnkPath);
}
catch(COMException ex)
{
    // The constructor wraps the root cause; check environment first.
    if(!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        throw new PlatformNotSupportedException(
            "ShellLink requires Windows with shell32.", ex);
    throw new InvalidOperationException(
        "Shell COM activation failed. Ensure STA thread and shell32 registration.", ex);
}
finally
{
    link?.Dispose();
}

Prevention

When it happens

Trigger: Calling new ShellLink() (or new ShellLink(path)) on a non-Windows platform, on a thread that has not entered a compatible COM apartment (STA is expected by shell COM objects), or in an environment where the Shell.CLSID {00021401-0000-0000-C000-000000000046} is not registered. Also possible when shell32.dll is corrupted or the process runs in a sandbox container without shell COM access.

Common situations: Running unit tests on Linux/macOS CI without COM. Running as a Windows service under a non-interactive session where shell COM is restricted. Forgetting [STAThread] on the entry point, causing MTA-threaded COM activation of an STA-only object. Using a trimmed/self-contained .NET publish that strips COM interop support.

Related errors


AI-assisted analysis of BluePointLilac/ContextMenuManager@55507155dd (2026-08-13). Data as JSON: /api/errors/bc2cc9072005b7c4. Report an issue: GitHub.