stride3d/stride · error · Exception
Failed to unregister a mouse device for raw input
Error message
Failed to unregister a mouse device for raw input
What it means
RawInputMouse.End unregisters the mouse device by calling RawInput.RegisterDevice with RIDEV_REMOVE and a null target window. If that Win32 call fails, the library throws this exception while tearing down input, typically from Dispose.
Solutions
- Ensure End() is called at most once and only after a successful Start().
- Dispose input before destroying the target window during shutdown.
- Make the remove flags/hwnd parameters match the original registration; retry on a valid message window if needed.
- Wrap Dispose so a failure here is logged rather than masking the original shutdown exception.
Example fix
// before
public void Dispose() { End(); End(); } // second End throws
// after
private bool ended;
public void Dispose() { if (ended) return; ended = true; End(); } Defensive patterns
Strategy: try-catch
Validate before calling
if (started) End(); // only unregister after a successful Start
Type guard
bool CanEnd(RawInputMouse m) => m != null && m.Started && !m.Disposed;
Try / catch
try { mouse.End(); } catch (Exception ex) when (ex.Message.Contains("Failed to unregister a mouse device")) { Log.Warn(ex); /* continue teardown */ } Prevention
- Make Start/End symmetric and call End at most once (guard with a bool)
- Dispose input components before disposing the window during shutdown
- Swallow-and-log teardown failures so they don't mask original errors
- Never call End after a failed Start without re-checking state
When it happens
Trigger: Calling End()/Dispose() when the mouse device is not currently registered (Start never succeeded or End called twice), or when the RIDEV_REMOVE registration is rejected because the remove parameters do not match an existing registration.
Common situations: Double-dispose of the RawInputMouse; disposing after a failed Start; window handle already destroyed so the remove request cannot be matched; application shutdown ordering removes the window before input disposal.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to register a mouse device for raw input
- uiControl
- Could not locate "Program Files" folder.
- Could not start install package process
- Couldn't unlock file.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/d24dfe522cca0811.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/Windows/RawInput/RawInputMouse.cs:46
public void Start()
{
var result = RawInput.RegisterDevice(UsagePage.HID_USAGE_PAGE_GENERIC, UsageId.HID_USAGE_GENERIC_MOUSE, ModeFlags.RIDEV_INPUTSINK, targetWindow);
if (!result)
{
throw new Exception("Failed to register a mouse device for raw input");
}
Application.AddMessageFilter(messageFilter);
}
public void End()
{
Application.RemoveMessageFilter(messageFilter);
var result = RawInput.RegisterDevice(UsagePage.HID_USAGE_PAGE_GENERIC, UsageId.HID_USAGE_GENERIC_MOUSE, ModeFlags.RIDEV_REMOVE, IntPtr.Zero);
if (!result)
{
throw new Exception("Failed to unregister a mouse device for raw input");
}
}
public void HandleInputMessage(RawInput.RawMouse mouseInput)
{
// TODO: Handle absolute pointer positions. These events can happen with drawing tablets or RDP for example
events?.Invoke(null, new RawInputMouseEventArgs
{
isRelative = (mouseInput.Flags & MOUSE_MOVE_ABSOLUTE_BIT) == 0,
X = mouseInput.LastX,
Y = mouseInput.LastY
});
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{View on GitHub (pinned to 96fad776d2)