BluePointLilac/ContextMenuManager · warning · ArgumentException

Hotkey must include a modifier key.

Error message

Hotkey must include a modifier key.

What it means

The ShellLink.HotKey setter enforces that any assigned hotkey must include at least one modifier key (Ctrl, Alt, or Shift). Windows shortcut (.lnk) hotkeys are encoded as a two-byte value where the high byte stores modifier flags and the low byte stores the virtual-key code. The library throws ArgumentException when (value & Keys.Modifiers) == 0 because a modifier-less hotkey would produce a zero high byte, yielding an ambiguous or ineffective shortcut key.

Source

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

                return description.ToString();
            }
            set
            {
                shellLinkW.SetDescription(value);
            }
        }

        public Keys HotKey
        {
            get
            {
                shellLinkW.GetHotKey(out ushort key);
                int hotKey = ((key & 0xFF00) << 8) | (key & 0xFF);
                return (Keys)hotKey;
            }
            set
            {
                if((value & Keys.Modifiers) == 0) throw new ArgumentException("Hotkey must include a modifier key.");
                ushort key = unchecked((ushort)(((int)(value & Keys.Modifiers) >> 8) | (int)(value & Keys.KeyCode)));
                shellLinkW.SetHotKey(key);
            }
        }

        public FormWindowState WindowStyle
        {
            get
            {
                shellLinkW.GetShowCmd(out int style);
                switch(style)
                {
                    case SW_SHOWMINIMIZED:
                    case SW_SHOWMINNOACTIVE:
                        return FormWindowState.Minimized;
                    case SW_SHOWMAXIMIZED:
                        return FormWindowState.Maximized;
                    case SW_SHOWNORMAL:

View on GitHub (pinned to 55507155dd)

Solutions

  1. OR the desired key with a modifier: shellLink.HotKey = Keys.Control | Keys.F5
  2. Pre-validate with: if((hotkey & Keys.Modifiers) != 0) before assigning
  3. If you need a modifier-less shortcut, pick one of Keys.Control, Keys.Alt, or Keys.Shift as the minimum required companion

Example fix

// before
shellLink.HotKey = Keys.F5;

// after
shellLink.HotKey = Keys.Control | Keys.F5;
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidHotKey(Keys key)
{
    return (key & Keys.Modifiers) != 0
        && (key & Keys.KeyCode) != 0;
}

// Usage:
if(IsValidHotKey(desiredKey))
    shellLink.HotKey = desiredKey;
else
    ShowUser("Hotkey must include Ctrl, Alt, or Shift.");

Type guard

static bool IsHotKeyWithModifier(Keys key) => (key & Keys.Modifiers) != 0;

Prevention

When it happens

Trigger: Assigning shellLink.HotKey = Keys.F5 (or any single virtual key without OR-ing in Keys.Control, Keys.Alt, or Keys.Shift). Also triggered by assigning Keys.None or any Keys enum value whose bits do not overlap with the Keys.Modifiers mask (0x000F0000).

Common situations: Developer assigns a bare function key or letter key expecting the OS to apply a default modifier. Developer constructs the Keys value from an index or enum mapping that omits modifier bits. Passing a raw ConsoleKey or integer cast to Keys that lacks modifier flags.

Related errors


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