Function FindTheHid() As Boolean 'Makes a series of API calls to locate the desired HID-class device. 'Returns True if the device is detected, False if not detected.Dim Count As Integer Dim GUIDString As String Dim HidGuid As GUID Dim MemberIndex As LongLastDevice = False MyDeviceDetected = FalseResult = HidD_GetHidGuid(HidGuid) Call DisplayResultOfAPICall("GetHidGuid")'Display the GUID. GUIDString = _ Hex$(HidGuid.Data1) & "-" & _ Hex$(HidGuid.Data2) & "-" & _ Hex$(HidGuid.Data3) & "-"For Count = 0 To 7 'Ensure that each of the 8 bytes in the GUID displays two characters. If HidGuid.Data4(Count) >= &H10 Then GUIDString = GUIDString & Hex$(HidGuid.Data4(Count)) & " " Else GUIDString = GUIDString & "0" & Hex$(HidGuid.Data4(Count)) & " " End If Next Count DeviceInfoSet = SetupDiGetClassDevs _ (HidGuid, _ vbNullString, _ 0, _ (DIGCF_PRESENT Or DIGCF_DEVICEINTERFACE))
Call DisplayResultOfAPICall("SetupDiClassDevs") DataString = GetDataString(DeviceInfoSet, 32)'Begin with 0 and increment until no more devices are detected. MemberIndex = 0Do 'The cbSize element of the MyDeviceInterfaceData structure must be set to 'the structure's size in bytes. The size is 28 bytes. MyDeviceInterfaceData.cbSize = LenB(MyDeviceInterfaceData) Result = SetupDiEnumDeviceInterfaces _ (DeviceInfoSet, _ 0, _ HidGuid, _ MemberIndex, _ MyDeviceInterfaceData)
Call DisplayResultOfAPICall("SetupDiEnumDeviceInterfaces") If Result = 0 Then LastDevice = True
' Call DisplayResultOfAPICall("SetupDiGetDeviceInterfaceDetail") ' lstResults.AddItem " (OK to say too small)" ' lstResults.AddItem " Required buffer size for the data: " & Needed
'Store the structure's size. MyDeviceInterfaceDetailData.cbSize = _ Len(MyDeviceInterfaceDetailData)
'Use a byte array to allocate memory for 'the MyDeviceInterfaceDetailData structure ReDim DetailDataBuffer(Needed) 'Store cbSize in the first four bytes of the array. Call RtlMoveMemory _ (DetailDataBuffer(0), _ MyDeviceInterfaceDetailData, _ 4)
'Call SetupDiGetDeviceInterfaceDetail again. 'This time, pass the address of the first element of DetailDataBuffer 'and the returned required buffer size in DetailData. Result = SetupDiGetDeviceInterfaceDetail _ (DeviceInfoSet, _ MyDeviceInterfaceData, _ VarPtr(DetailDataBuffer(0)), _ DetailData, _ Needed, _ 0)
Call DisplayResultOfAPICall(" Result of second call: ") ' lstResults.AddItem " MyDeviceInterfaceDetailData.cbSize: " & _ ' CStr(MyDeviceInterfaceDetailData.cbSize)
'Convert the byte array to a string. DevicePathName = CStr(DetailDataBuffer()) 'Convert to Unicode. DevicePathName = StrConv(DevicePathName, vbUnicode) 'Strip cbSize (4 bytes) from the beginning. DevicePathName = Right$(DevicePathName, Len(DevicePathName) - 4)
Call DisplayResultOfAPICall("HidD_GetAttributes") If Result <> 0 Then ' lstResults.AddItem " HIDD_ATTRIBUTES structure filled without error." Else '' lstResults.AddItem " Error in filling HIDD_ATTRIBUTES structure." MsgBox "USB接口连接错误" End If
'Find out if the device matches the one we're looking for. If (DeviceAttributes.VendorID = MyVendorID) And _ (DeviceAttributes.ProductID = MyProductID) Then ' lstResults.AddItem " My device detected" MyDeviceDetected = True Else MyDeviceDetected = False 'If it's not the one we want, close its handle. Result = CloseHandle _ (HidDevice) DisplayResultOfAPICall ("CloseHandle") End If End If 'Keep looking until we find the device or there are no more left to examine. MemberIndex = MemberIndex + 1Loop Until (LastDevice = True) Or (MyDeviceDetected = True)If MyDeviceDetected = True Then FindTheHid = True StatusBar1.Panels.Item(2).Text = "" Else ' lstResults.AddItem " Device not found." err: MsgBox "请确保仪器联机!", 64, "提示" StatusBar1.Panels.Item(2).Text = "设备没有连接,请检查USB接口!" Exit Function
加个 判断Result = HidD_GetAttributes _ (HidDevice, _ DeviceAttributes) 是否成功。If Result > 0 Then Call DisplayResultOfAPICall("HidD_GetAttributes") 'Find out if the device matches the one we're looking for. If (DeviceAttributes.VendorID = MyVendorID) And _ (DeviceAttributes.ProductID = MyProductID) Then MyDeviceDetected = True Else MyDeviceDetected = False 'If it's not the one we want, close its handle. Result = CloseHandle _ (HidDevice) DisplayResultOfAPICall ("CloseHandle") End If End If 可以试下。
你写的代码,留着句柄 HidDevice 总有用吧? 如果不考虑其它,常规来说应该是 'Find out if the device matches the one we're looking for. If (DeviceAttributes.VendorID = MyVendorID) And _ (DeviceAttributes.ProductID = MyProductID) Then MyDeviceDetected = True Else MyDeviceDetected = False End If Result = CloseHandle(HidDevice) DisplayResultOfAPICall ("CloseHandle")
VB-IDE 为了应对调试时的非正常终止,对某些资源会进行自动释放,而 exe 运行就没有这个优待了。
'Makes a series of API calls to locate the desired HID-class device.
'Returns True if the device is detected, False if not detected.Dim Count As Integer
Dim GUIDString As String
Dim HidGuid As GUID
Dim MemberIndex As LongLastDevice = False
MyDeviceDetected = FalseResult = HidD_GetHidGuid(HidGuid)
Call DisplayResultOfAPICall("GetHidGuid")'Display the GUID.
GUIDString = _
Hex$(HidGuid.Data1) & "-" & _
Hex$(HidGuid.Data2) & "-" & _
Hex$(HidGuid.Data3) & "-"For Count = 0 To 7
'Ensure that each of the 8 bytes in the GUID displays two characters.
If HidGuid.Data4(Count) >= &H10 Then
GUIDString = GUIDString & Hex$(HidGuid.Data4(Count)) & " "
Else
GUIDString = GUIDString & "0" & Hex$(HidGuid.Data4(Count)) & " "
End If
Next Count
DeviceInfoSet = SetupDiGetClassDevs _
(HidGuid, _
vbNullString, _
0, _
(DIGCF_PRESENT Or DIGCF_DEVICEINTERFACE))
Call DisplayResultOfAPICall("SetupDiClassDevs")
DataString = GetDataString(DeviceInfoSet, 32)'Begin with 0 and increment until no more devices are detected.
MemberIndex = 0Do
'The cbSize element of the MyDeviceInterfaceData structure must be set to
'the structure's size in bytes. The size is 28 bytes.
MyDeviceInterfaceData.cbSize = LenB(MyDeviceInterfaceData)
Result = SetupDiEnumDeviceInterfaces _
(DeviceInfoSet, _
0, _
HidGuid, _
MemberIndex, _
MyDeviceInterfaceData)
Call DisplayResultOfAPICall("SetupDiEnumDeviceInterfaces")
If Result = 0 Then LastDevice = True
'If a device exists, display the information returned.
If Result <> 0 Then
' lstResults.AddItem " DeviceInfoSet for device #" & CStr(MemberIndex) & ": "
' lstResults.AddItem " cbSize = " & CStr(MyDeviceInterfaceData.cbSize)
' lstResults.AddItem _
' " InterfaceClassGuid.Data1 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data1)
' lstResults.AddItem _
' " InterfaceClassGuid.Data2 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data2)
' lstResults.AddItem _
' " InterfaceClassGuid.Data3 = " & Hex$(MyDeviceInterfaceData.InterfaceClassGuid.Data3)
' lstResults.AddItem _
' " Flags = " & Hex$(MyDeviceInterfaceData.Flags)
MyDeviceInfoData.cbSize = Len(MyDeviceInfoData)
Result = SetupDiGetDeviceInterfaceDetail _
(DeviceInfoSet, _
MyDeviceInterfaceData, _
0, _
0, _
Needed, _
0)
DetailData = Needed
' Call DisplayResultOfAPICall("SetupDiGetDeviceInterfaceDetail")
' lstResults.AddItem " (OK to say too small)"
' lstResults.AddItem " Required buffer size for the data: " & Needed
'Store the structure's size.
MyDeviceInterfaceDetailData.cbSize = _
Len(MyDeviceInterfaceDetailData)
'Use a byte array to allocate memory for
'the MyDeviceInterfaceDetailData structure
ReDim DetailDataBuffer(Needed)
'Store cbSize in the first four bytes of the array.
Call RtlMoveMemory _
(DetailDataBuffer(0), _
MyDeviceInterfaceDetailData, _
4)
'Call SetupDiGetDeviceInterfaceDetail again.
'This time, pass the address of the first element of DetailDataBuffer
'and the returned required buffer size in DetailData.
Result = SetupDiGetDeviceInterfaceDetail _
(DeviceInfoSet, _
MyDeviceInterfaceData, _
VarPtr(DetailDataBuffer(0)), _
DetailData, _
Needed, _
0)
Call DisplayResultOfAPICall(" Result of second call: ")
' lstResults.AddItem " MyDeviceInterfaceDetailData.cbSize: " & _
' CStr(MyDeviceInterfaceDetailData.cbSize)
'Convert the byte array to a string.
DevicePathName = CStr(DetailDataBuffer())
'Convert to Unicode.
DevicePathName = StrConv(DevicePathName, vbUnicode)
'Strip cbSize (4 bytes) from the beginning.
DevicePathName = Right$(DevicePathName, Len(DevicePathName) - 4)
HidDevice = CreateFile _
(DevicePathName, _
GENERIC_READ Or GENERIC_WRITE, _
(FILE_SHARE_READ Or FILE_SHARE_WRITE), _
0, _
OPEN_EXISTING, _
0, _
0)
Call DisplayResultOfAPICall("CreateFile") DeviceAttributes.Size = LenB(DeviceAttributes)
Result = HidD_GetAttributes _
(HidDevice, _
DeviceAttributes)
Call DisplayResultOfAPICall("HidD_GetAttributes")
If Result <> 0 Then
' lstResults.AddItem " HIDD_ATTRIBUTES structure filled without error."
Else
'' lstResults.AddItem " Error in filling HIDD_ATTRIBUTES structure."
MsgBox "USB接口连接错误"
End If
' lstResults.AddItem " Structure size: " & DeviceAttributes.Size
' lstResults.AddItem " Vendor ID: " & Hex$(DeviceAttributes.VendorID)
' lstResults.AddItem " Product ID: " & Hex$(DeviceAttributes.ProductID)
' lstResults.AddItem " Version Number: " & Hex$(DeviceAttributes.VersionNumber)
'Find out if the device matches the one we're looking for.
If (DeviceAttributes.VendorID = MyVendorID) And _
(DeviceAttributes.ProductID = MyProductID) Then
' lstResults.AddItem " My device detected"
MyDeviceDetected = True
Else
MyDeviceDetected = False
'If it's not the one we want, close its handle.
Result = CloseHandle _
(HidDevice)
DisplayResultOfAPICall ("CloseHandle")
End If
End If
'Keep looking until we find the device or there are no more left to examine. MemberIndex = MemberIndex + 1Loop Until (LastDevice = True) Or (MyDeviceDetected = True)If MyDeviceDetected = True Then
FindTheHid = True
StatusBar1.Panels.Item(2).Text = ""
Else
' lstResults.AddItem " Device not found."
err: MsgBox "请确保仪器联机!", 64, "提示"
StatusBar1.Panels.Item(2).Text = "设备没有连接,请检查USB接口!"
Exit Function
End IfEnd Function
不会的。而且除非独占打开,USB 设备即使没有释放也还是可以再打开。看看你编译前是否注掉了什么必要的语句。
(HidDevice, _
DeviceAttributes) 是否成功。If Result > 0 Then
Call DisplayResultOfAPICall("HidD_GetAttributes")
'Find out if the device matches the one we're looking for.
If (DeviceAttributes.VendorID = MyVendorID) And _
(DeviceAttributes.ProductID = MyProductID) Then
MyDeviceDetected = True
Else
MyDeviceDetected = False
'If it's not the one we want, close its handle.
Result = CloseHandle _
(HidDevice)
DisplayResultOfAPICall ("CloseHandle")
End If
End If
可以试下。
全编译执行正常
生成.exe程序后出现 MsgBox "USB接口连接错误"
err: MsgBox "请确保仪器联机!", 64, "提示"
如果去掉上面的msgbox后
运行程序直接出现运行错误,强行退出
(DevicePathName, _
GENERIC_READ Or GENERIC_WRITE, _
(FILE_SHARE_READ Or FILE_SHARE_WRITE), _
0, _
OPEN_EXISTING, _
0, _
0) If HidDevice = -1 Then '判断CreateFile是否成功,一直检测
GoTo ERR_DEVICE
End If......
ERR_DEVICE:
MemberIndex = MemberIndex + 1Loop Until (LastDevice = True) Or (MyDeviceDetected = True)很多时候创建不了的。
那么这段代码如何加呢?
谢谢你了
如果不考虑其它,常规来说应该是
'Find out if the device matches the one we're looking for.
If (DeviceAttributes.VendorID = MyVendorID) And _
(DeviceAttributes.ProductID = MyProductID) Then
MyDeviceDetected = True
Else
MyDeviceDetected = False
End If
Result = CloseHandle(HidDevice)
DisplayResultOfAPICall ("CloseHandle")
这样修改就找不到设备了