/// <summary> /// Enumerates list of PlugNPlay devices connected to the system. /// Finds ones that match XBox Controller signature. /// Extracts and returns number that matches first 4 bytes of devices' DirectInput ProductGuid. /// </summary> /// <param name="collection">ManagementObjectCollection retrieved from WMI.</param> /// <returns> /// For each XBox controller found returns: /// string representation of 8 digits hexa number /// that matches first 4 bytes of that device's DirectInput ProductGuid. /// </returns> public static string[] GetAllXInputDevicesVIDPIDsFromPnPDevices_AsStrings(ManagementObjectCollection collection) { List <string> xb_VIDPIDs = new List <string>(); string deviceID; foreach (ManagementObject obj in collection) { deviceID = (string)obj.GetPropertyValue("DeviceID"); if (deviceID.Contains(XInputDeviceIDMarker)) { xb_VIDPIDs.Add(Get_PID_VID(deviceID)); } } var comparerOrdNoCase = new StringEqualityComparerOrdinalNoCase(); return(xb_VIDPIDs.Distinct(comparerOrdNoCase).ToArray()); }
/// <summary> /// Normally for internal use only. Call if user has attached new Gamepads, /// or detached Gamepads you want discarded. /// Otherwise, loaded once on first Devices request and does not reflect changes in gamepads attachment. /// TODO: Do this better ? /// </summary> public static void ReloadDevices() { if (_Devices == null) { _Devices = new List <DirectInputGamepad>(16); } else { _Devices.Clear(); } // gamepads are generally misidentified as Joysticks in DirectInput... get both var devices = Enumerable.Concat( Manager.GetDevices(DeviceType.Gamepad, EnumDevicesFlags.AttachedOnly) .Cast <DeviceInstance>() .Select(di => new { DeviceInstance = di, GamingDeviceType = GamingDeviceType.Gamepad }) , Manager.GetDevices(DeviceType.Joystick, EnumDevicesFlags.AttachedOnly) .Cast <DeviceInstance>() .Select(di => new { DeviceInstance = di, GamingDeviceType = GamingDeviceType.Joystick }) ); if (ExcludeXInputDevices) { uint[] xInputDevices_VIDPIDs = WMI.GetAllXInputDevicesVIDPIDsFromPnPDevices(); devices = devices .Where(dii => xInputDevices_VIDPIDs.Contains(dii.DeviceInstance.ProductGuid.PartA()) == false); } var comparerOrdNoCase = new StringEqualityComparerOrdinalNoCase(); var groups = devices //.GroupBy(di => di.ProductName, stringEqualityComparerOrdinal); .ToLookup(a => a.DeviceInstance.ProductName, comparerOrdNoCase); foreach (var group in groups) { if (group.Count() == 1) { var deviceInfo = group.First(); _Devices.Add( new DirectInputGamepad( deviceInfo.DeviceInstance, deviceInfo.DeviceInstance.ProductName, deviceInfo.GamingDeviceType ) ); } else { int i = 1; foreach (var deviceInfo in group) { _Devices.Add( new DirectInputGamepad( deviceInfo.DeviceInstance, $"{deviceInfo.DeviceInstance.ProductName} [{i}]", deviceInfo.GamingDeviceType ) ); i++; } } } }