/// <summary> /// 重新打开设备文件流 /// </summary> /// <param name="findDevice"></param> private void ReOpenDeviceFileStreamHandler(DeviceInformation findDevice) { //关闭句柄并用读/写模式重新打开 findDevice.HidHandle.Close(); findDevice.HidHandle = FileIODeclarations.CreateFile(findDevice.myDevicePathName, FileIODeclarations.GENERIC_READ | FileIODeclarations.GENERIC_WRITE, FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIODeclarations.OPEN_EXISTING, 0, 0); Debug.WriteLine("在函数ReOpenDeviceFileStreamHandler中" + this.MyDebugging.ResultOfAPICall("CreateFile")); if (findDevice.HidHandle.IsInvalid) { findDevice.ExclusiveAccess = true; Debug.WriteLine("此设备是一个系统" + findDevice.HidUsage + "." + "对于此设备,Windows 2000 和 Windows XP 才能使用 Input 和 Output reports功能."); } else { if (findDevice.Capabilities.InputReportByteLength > 0) { // Set the size of the Input report buffer. Byte[] inputReportBuffer = null; inputReportBuffer = new Byte[findDevice.Capabilities.InputReportByteLength]; findDevice.FileStreamDeviceData = new FileStream(findDevice.HidHandle, FileAccess.Read | FileAccess.Write, inputReportBuffer.Length, false); } // Flush any waiting reports in the input buffer. (optional) _hidObject.FlushQueue(findDevice.HidHandle); } }
/// <summary> /// 根据给定的VendorID和ProductID查找设备,并将其事件注册到窗体. /// </summary> /// <returns> /// 探测到返回True,没有返回False /// </returns> public Boolean findHidDevices(ref int myVendorID, ref int myProductID)//, Form FrmMy { Boolean deviceFound = false; String[] devicePathName = new String[128]; String functionName = ""; Guid hidGuid = Guid.Empty; Int32 memberIndex = 0; Boolean success = false; // 检查是否在重入 if (this._findHidIsBusy == true) { return(false); } else { this._findHidIsBusy = true; } if (this._deviceVID != myVendorID) { this._deviceVID = myVendorID; } if (this._devicePID != myVendorID) { this._devicePID = myProductID; } try { DeviceInformation device = new DeviceInformation(); device.DeviceIsDetected = false; // CloseCommunications(); // 调用API 函数: 'HidD_GetHidGuid HidDeclarations.HidD_GetHidGuid(ref hidGuid); Debug.WriteLine("在函数FindTheHid中" + this.MyDebugging.ResultOfAPICall("HidD_GetHidGuid")); // 获取连接的HID路径名称数组 deviceFound = this.FindDeviceFromGuid(hidGuid, ref devicePathName); // 如果至少有一个HID,获取每个设备的Vendor ID,Product ID,直到发现一个或者所有设备 if (deviceFound) { memberIndex = 0; do { // 调用API函数CreateFile if (devicePathName[memberIndex] != null && this[devicePathName[memberIndex]] != null) { if (this[devicePathName[memberIndex]] != null && this[devicePathName[memberIndex]].DeviceIsDetected) { memberIndex++; continue; // 继续查找下一个设备 } else { device = this[devicePathName[memberIndex]]; } } // 在不使用Read/write权限的情况下打开句柄,以获取HID的信息, 甚至系统键盘鼠标等 device.HidHandle = FileIODeclarations.CreateFile(devicePathName[memberIndex], 0, FileIODeclarations.FILE_SHARE_READ | FileIODeclarations.FILE_SHARE_WRITE, IntPtr.Zero, FileIODeclarations.OPEN_EXISTING, 0, 0); Debug.WriteLine("在函数FindTheHid中" + this.MyDebugging.ResultOfAPICall("CreateFile")); if (!device.HidHandle.IsInvalid) { // 返回的句柄是合法的,确定此设备是否我们要找的设备 // 设置DeviceAttributes中的数据字节结构 _hidObject.DeviceAttributes.Size = Marshal.SizeOf(_hidObject.DeviceAttributes); // 调用API函数 HidD_GetAttributes success = HidDeclarations.HidD_GetAttributes(device.HidHandle, ref _hidObject.DeviceAttributes); Debug.WriteLine("在函数FindTheHid中" + this.MyDebugging.ResultOfAPICall("HidD_GetAttributes")); if (success) { //Debug.WriteLine(" HIDD_ATTRIBUTES 结构被成功填充."); //Debug.WriteLine(" 结构大小: " + MyHid.DeviceAttributes.Size); //Debug.WriteLine(" Vendor ID: " + Convert.ToString(MyHid.DeviceAttributes.VendorID, 16)); //Debug.WriteLine(" Product ID: " + Convert.ToString(MyHid.DeviceAttributes.ProductID, 16)); //Debug.WriteLine(" 版本号: " + Convert.ToString(MyHid.DeviceAttributes.VersionNumber, 16)); // 确定是否我们要找的设备 if ((_hidObject.DeviceAttributes.VendorID == myVendorID) && (_hidObject.DeviceAttributes.ProductID == myProductID)) { // 窗口列表框中显示设备信息 Debug.WriteLine(" 探测到设备:" + " Vendor ID = " + Convert.ToString(_hidObject.DeviceAttributes.VendorID, 16) + " Product ID = " + Convert.ToString(_hidObject.DeviceAttributes.ProductID, 16)); device.DeviceIsDetected = true; // 为OnDeviceChange()函数保存设备路径名 if (this[devicePathName[memberIndex]] == null) { device.myDevicePathName = devicePathName[memberIndex]; device.DeviceAttributes = _hidObject.DeviceAttributes; this._deviceList.Add(device); device = new DeviceInformation(); _hidObject = new Hid(); device.DeviceIsDetected = false; Debug.WriteLine("将设备" + device.myDevicePathName + "加入到设备列表中"); } } else { // 如果不匹配关闭设备句柄 device.DeviceIsDetected = false; device.HidHandle.Close(); } } else { // 提示获取设备信息出现问题. Debug.WriteLine("Error in filling HIDD_ATTRIBUTES structure."); device.DeviceIsDetected = false; device.HidHandle.Close(); } } // 继续查找,直到我们发现给定设备或者检查完成 memberIndex = memberIndex + 1; }while (!((device.DeviceIsDetected || (memberIndex == devicePathName.Length)))); } if (this._deviceList.Count > 0) { for (int i = 0; i < this._deviceList.Count; i++) { DeviceInformation findDevice = this._deviceList[i]; if (findDevice.Capabilities.InputReportByteLength > 0) { continue; } // 如果探测到设备 // 注册关注设备事件 Register to receive notifications if the device is removed or attached. success = this.RegisterForDeviceNotifications(findDevice.myDevicePathName, this.Handle /*FrmMy.Handle*/, hidGuid, ref findDevice.DeviceNotificationHandle); Debug.WriteLine("RegisterForDeviceNotifications = " + success); // 获取设备信息 findDevice.Capabilities = _hidObject.GetDeviceCapabilities(findDevice.HidHandle); if (success) { // 确定是否鼠标或键盘设备 findDevice.HidUsage = _hidObject.GetHidUsage(_hidObject.Capabilities); // 获取报告的缓冲区大小 GetInputReportBufferSize(findDevice); this.ReOpenDeviceFileStreamHandler(findDevice); } } for (int i = this._deviceList.Count - 1; i >= 0; i--) { if (!this._deviceList[i].DeviceIsDetected) { this._deviceList.RemoveAt(i); } } } else { // 没有检测到设备 Debug.WriteLine("没发现设备."); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } this._findHidIsBusy = false; return(this._deviceList.Count > 0); }