babalae/better-genshin-impact · error · Win32Exception

注册 Raw Input 鼠标设备失败

Error message

注册 Raw Input 鼠标设备失败

What it means

RegisterRawInputDevices (the Win32 API) returns false when registration fails; RawInputMonitor throws a Win32Exception built from Marshal.GetLastPInvokeError(). The device registered is the mouse with RIDEV_INPUTSINK (receive input even when not foreground) bound to the message-only HWND. Failure typically means the HWND target is invalid or the session disallows raw input.

Solutions

  1. Inspect the NativeErrorCode in the Win32Exception to map the exact Win32 failure.
  2. Ensure Start() is not racing with Stop()/Dispose() that destroys the HWND.
  3. Run in an interactive desktop session; fall back to DirectInput if unavailable.
  4. Retry registration after recreating the HWND.

Example fix

// before
monitor.Start();

// after
try
{
    monitor.Start();
}
catch (Win32Exception ex) when (ex.Message.Contains("注册 Raw Input 鼠标设备失败"))
{
    logger.LogError("RawInput 注册失败 Win32Error={Code}", ex.NativeErrorCode);
    throw;
}
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    monitor.Start();
}
catch (System.ComponentModel.Win32Exception ex) when (ex.Message.Contains("注册 Raw Input 鼠标设备失败"))
{
    logger.LogError("RawInput 注册失败 Win32Error={Code}", ex.NativeErrorCode);
    // fall back to DirectInput if available
}

Prevention

When it happens

Trigger: context.HwndSource.Handle is zero/disposed at registration time; running in a non-interactive session; another process holds an incompatible raw-input registration; insufficient privileges for INPUTSINK.

Common situations: RDP/session transitions disposing the HWND; rapid Start/Stop where the HWND was torn down; headless/service hosting; security software blocking raw input.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/572ca7d35e459694. Report an issue: GitHub.

Appendix: source

Thrown at BetterGenshinImpact/Core/Monitor/RawInputMonitor.cs:328

    private void RegisterRawInput(RawInputThreadContext context)
    {
        var devices = new[]
        {
            new User32.RAWINPUTDEVICE
            {
                usUsagePage = GenericDesktopUsagePage,
                usUsage = MouseUsage,
                dwFlags = User32.RIDEV.RIDEV_INPUTSINK,
                hwndTarget = context.HwndSource!.Handle
            }
        };

        if (!User32.RegisterRawInputDevices(
                devices,
                (uint)devices.Length,
                (uint)Marshal.SizeOf<User32.RAWINPUTDEVICE>()))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "注册 Raw Input 鼠标设备失败");
        }
    }

    private void CleanupContext(RawInputThreadContext context)
    {
        if (context.Registered)
        {
            var devices = new[]
            {
                new User32.RAWINPUTDEVICE
                {
                    usUsagePage = GenericDesktopUsagePage,
                    usUsage = MouseUsage,
                    dwFlags = User32.RIDEV.RIDEV_REMOVE,
                    hwndTarget = HWND.NULL
                }
            };

View on GitHub (pinned to a7cb36712d)