You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用DirectInput的GetDevices()方法时程序挂起无响应:C#环境下DirectX摇杆输入获取问题求助

DirectInput Manager.GetDevices()导致程序挂起的排查与解决

我之前也碰到过类似的DirectInput枚举设备挂起的问题,这种无响应通常和几个常见的坑有关,咱们一步步来拆解排查:

1. 优先检查线程模型(最常见原因)

DirectInput依赖的COM组件很多要求在**单线程单元(STA)**环境下运行,而C#控制台程序默认是多线程单元(MTA)。这个不匹配很容易导致枚举设备时挂起。

解决方法很简单,给Main方法加上[STAThread]特性:

using Microsoft.DirectX.DirectInput;
namespace Input
{
    class Controller
    {
        static void InitJoystick()
        {
            foreach (DeviceInstance di in Manager.GetDevices(
                DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly))
            {
                Console.WriteLine(di.InstanceGuid);
            }
        }

        [STAThread] // 关键:添加这个特性
        static void Main(string[] args)
        {
            InitJoystick();
        }
    }
}

2. 排查设备驱动与兼容性问题

有些老旧摇杆的驱动和新版DirectInput兼容性差,或者系统里存在损坏的输入设备驱动,也会导致枚举过程卡住:

  • 卸载摇杆的现有驱动,重新安装官方提供的最新版本
  • 打开设备管理器,禁用/启用可疑的输入设备(比如不知名的HID设备)
  • 在其他机器上测试你的代码,排除硬件本身的故障

3. 确保DirectX库与系统架构匹配

如果你的项目目标平台(x86/x64)和引用的DirectInput库架构不匹配,很可能出现无响应的情况:

  • 检查项目属性里的“目标平台”设置,确保和你引用的DirectX库位数一致
  • 尽量使用对应系统版本的DirectX SDK库,避免混用不同版本的组件

4. 添加异常捕获,挖掘隐藏错误

虽然你说没抛出错误,但可能是枚举过程中出现了未被捕获的COM异常。给枚举代码套个try-catch,看看有没有隐藏的错误信息:

static void InitJoystick()
{
    try
    {
        foreach (DeviceInstance di in Manager.GetDevices(
            DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly))
        {
            Console.WriteLine(di.InstanceGuid);
        }
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        Console.WriteLine($"COM异常: {ex.Message}, 错误码: {ex.ErrorCode}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"其他异常: {ex.Message}");
    }
}

5. 换用更可控的枚举方式

有时候直接遍历Manager.GetDevices()会有潜在问题,可以尝试用枚举器手动控制枚举过程:

static void InitJoystick()
{
    try
    {
        DeviceEnumerator enumerator = Manager.GetDevicesEnumerator(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly);
        while (enumerator.MoveNext())
        {
            DeviceInstance di = enumerator.Current;
            Console.WriteLine(di.InstanceGuid);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"枚举出错: {ex.Message}");
    }
}

建议先从线程模型的修改开始尝试,这个是最容易触发也最容易解决的问题。

内容的提问来源于stack exchange,提问作者erwfvsdcs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:32:46