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

Go语言如何获取Windows平台已连接摇杆的可用ID列表

Windows平台无依赖枚举摇杆设备ID方案

你使用的摇杆读取库底层本身就是调用Windows原生WinMM(Windows多媒体)系统接口实现的,不需要引入任何需要用户额外安装的第三方依赖,直接通过标准库调用系统自带接口即可完成设备枚举,拿到可直接传入joystick.Open()的有效joy_id。
WinMM是Windows从XP到Win11全版本默认预装的系统组件,编译后的程序是单二进制文件,不需要用户额外安装SDL、运行库等任何附加软件,完全适配非技术用户的使用场景。

核心逻辑

WinMM的摇杆设备ID从0开始连续编号:

  • 首先调用joyGetNumDevs接口获取系统支持的最大摇杆设备数量上限
  • 从ID=0开始逐个校验,调用joyGetDevCaps接口判断对应ID的设备是否真实接入、可用
  • 所有校验通过的ID就是可直接使用的有效joy_id

可直接复用的实现代码

通过Go标准库syscall直接调用系统winmm.dll导出的接口即可,不需要引入额外第三方包:

package main

import (
	"syscall"
	"unsafe"
)

var (
	winmm              = syscall.NewLazyDLL("winmm.dll")
	procJoyGetNumDevs  = winmm.NewProc("joyGetNumDevs")
	procJoyGetDevCapsW = winmm.NewProc("joyGetDevCapsW")
)

// JOYCAPS 对应WinMM接口的设备信息结构体,仅保留校验必要字段
type JOYCAPS struct {
	ManufacturerID uint16
	ProductID      uint16
	DriverName     [32]uint16
	ProductName    [32]uint16
	_              [224]byte // 占位剩余不需要读取的结构体字段
}

const joyErrNoError = 0

// GetAvailableJoystickIDs 返回所有当前接入可用的摇杆ID,可直接传入joystick.Open使用
func GetAvailableJoystickIDs() []uint32 {
	var validIDs []uint32
	maxDevNum, _, _ := procJoyGetNumDevs.Call()

	for id := uint32(0); id < uint32(maxDevNum); id++ {
		var caps JOYCAPS
		ret, _, _ := procJoyGetDevCapsW.Call(
			uintptr(id),
			uintptr(unsafe.Pointer(&caps)),
			uintptr(unsafe.Sizeof(caps)),
		)
		if ret == joyErrNoError {
			validIDs = append(validIDs, id)
		}
	}
	return validIDs
}

使用注意事项

  • 枚举得到的ID和摇杆库要求的参数完全匹配,不需要做额外转换,遍历传入joystick.Open()即可正常打开设备。
  • 设备ID会随手柄插拔动态变化,如果程序需要支持热插拔,定时重新调用该枚举函数刷新设备列表即可。
  • 枚举结果和Windows系统自带的「游戏控制器」控制面板里显示的设备完全一致,包括正规手柄、虚拟手柄等所有被系统识别的摇杆类设备。
  • 跨平台适配时,Linux下可通过枚举/dev/input/js*设备节点获取对应设备ID,macOS下可通过IOKit框架接口枚举,Windows下使用上述方案即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 08:24:22