1
Vote

DirectInputException exception after disconnecting device

description

I was trying to make my XNA program more robust by checking to see if a joystick was connected before reading the state, so I started out by calling Update() on my Nuclex.Input.InputManager object. After disconnecting the joystick while running the program, I got a DirectInputException (exception output is shown below). Someone using SlimDX had the same issue a while back (http://code.google.com/p/slimdx/issues/detail?id=828) and it was closed by an update to SlimDX.
 
Is there a proper fix or workaround to this issue?
 
 
Here's my temporary fix to the issue:
  1. I downloaded the latest (January 2012) .NET 4.0 x86 DLLs for SlimDX.
  2. Downloaded the source code for the current (r1404) release of Nuclex.
  3. Changed the Nuclex.Input reference from the SlimDX.DirectInput.dll to the SlimDX.dll I downloaded in step 1.
  4. Added the following lines to the queryState() method in \nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\Devices\DirectInputGamePad.cs:
     
    if (!this.IsAttached)
    {
    return false;
    }
     
     
    The method (without comments) now looks like:
     
     
    private bool queryState() {
    Result result;
     
    if (!this.IsAttached)
    {
      return false;
    }

    if (!this.currentlyAcquired) {
    result = this.joystick.Acquire();
    if (result == ResultCode.InputLost) {
      return false;
    }
     
    this.currentlyAcquired = true;
    }
     
    result = this.joystick.Poll();
    if (result == ResultCode.InputLost) {
    this.currentlyAcquired = false;
    return false;
    }
     
    if (this.states.Items[this.states.TailIndex] == null) {
    this.states.Items[this.states.TailIndex] = new JoystickState();
    }
    result = this.joystick.GetCurrentState(ref this.states.Items[this.states.TailIndex]);
    if (result == ResultCode.InputLost) {
    this.currentlyAcquired = false;
    return false;
    }
     
    return true;
    }
     
     
    With these changes, I'm able to run my program and disconnect the joystick without getting any exceptions. Also, I can plug it back in and it is detected by the program.
     
    The only drawback (so far) is that I have to use the larger SlimDX.dll.
     
     
     
    Here is the exception output:
     
    SlimDX.DirectInput.DirectInputException was unhandled
    HResult=-2146233088
    Message=E_FAIL: An undetermined error occurred (-2147467259)
    Source=SlimDX.DirectInput
    StackTrace:
    at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
    at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
    at SlimDX.Result.Record[T](Int32 hr, Object dataKey, Object dataValue)
    at SlimDX.DirectInput.DirectInput.IsDeviceAttached(Guid device)
    at Nuclex.Input.DirectInputManager.IsDeviceAttached(Device device) in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\DirectInputManager.cs:line 76
    at Nuclex.Input.Devices.DirectInputGamePad.get_IsAttached() in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\Devices\DirectInputGamePad.cs:line 78
    at Nuclex.Input.Devices.DirectInputGamePad.queryState() in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\Devices\DirectInputGamePad.cs:line 137
    at Nuclex.Input.Devices.DirectInputGamePad.Update() in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\Devices\DirectInputGamePad.cs:line 109
    at Nuclex.Input.InputManager.Update() in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\InputManager.cs:line 216
    at Nuclex.Input.InputManager.Microsoft.Xna.Framework.IUpdateable.Update(GameTime gameTime) in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\nuclex-framework-r1404-sources\framework\Nuclex.Input\Source\InputManager.cs:line 278
    at Microsoft.Xna.Framework.Game.Update(GameTime gameTime)
    at P5CTSFlightSim.Game1.Update(GameTime gameTime) in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\P5CTSFlightSim\P5CTSFlightSim\P5CTSFlightSim\Game1.cs:line 362
    at Microsoft.Xna.Framework.Game.Tick()
    at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
    at Microsoft.Xna.Framework.GameHost.OnIdle()
    at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
    at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
    at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
    at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    at System.Windows.Forms.Application.Run(Form mainForm)
    at Microsoft.Xna.Framework.WindowsGameHost.Run()
    at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
    at Microsoft.Xna.Framework.Game.Run()
    at P5CTSFlightSim.Program.Main(String[] args) in C:\Users\prbarcelon\Documents\Visual Studio 2010\Projects\P5CTSFlightSim\P5CTSFlightSim\P5CTSFlightSim\Program.cs:line 15
    InnerException:
     
    Also attached is the modified DirectInputGamePad.cs file.

file attachments

comments