【已解决】输出的USB参数如何转换成端口名称
本帖最后由 itzyx 于 2022-3-12 13:44 编辑论坛找了一个 水木子大大写的检测USB 插入插出的一个简单的例子:
Global Const $WM_DEVICECHANGE = 537 ;设备发生改变
Global Const $DBT_DEVICEARRIVAL = 0x8000 ;设备插入
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ;设备移除
GUIRegisterMsg($WM_DEVICECHANGE, 'My_Message_Test')
GUICreate('')
Do
Until GUIGetMsg() = -3
Func My_Message_Test($hWnd, $Msg, $wParam, $lParam)
Switch $wParam
Case $DBT_DEVICEARRIVAL
MsgBox(0, '提示!', '检测到设备插入 - ' & $lParam)
Case $DBT_DEVICEREMOVECOMPLETE
MsgBox(0, '提示!', '检测到设备被移除 - ' & $lParam)
EndSwitch
EndFunc ;==>My_Message_Test我现在想把输出结果 $lParam 改成端口名称,如图所示,不知道如何转换,麻烦各位大佬指点一下,万分感谢。
itzyx 发表于 2022-3-11 22:51
发哥 还是不行
我玩了个嘚~~~ WM_DEVICECHANGE连接或断开设备时发送此消息.参 数这些参数被传递到系统.
$wParam连接或断开标志
$DBT_DEVICEARRIVAL = 0x8000 ; 新的设备已连接并准备好使用.
$DBT_DEVICEQUERYREMOVE = 0x8001 ; 请求删除设备. 任何应用程序可以取消删除操作. 若要允许删除, 必须返回 TRUE. 若要取消删除, 应返回 BROADCAST_QUERY_DENY.
$DBT_DEVICEQUERYREMOVEFAILED = 0x8002 ; 删除的设备被中断.
$DBT_DEVICEREMOVEPENDING = 0x8003 ; 当前设备将被删除. 不能撤消删除操作. 返回 TRUE.
$DBT_DEVICEREMOVECOMPLETE = 0x8004 ; 设备被禁用.
$DBT_DEVICETYPESPECIFIC = 0x8005 ; 特定事件.
$DBT_DEVNODES_CHANGED = 0x0007 ; 硬件配置文件的任何变化.
$lParam结构的指针
$DEV_BROADCAST_HDR 结构, 指定跟踪的设备类型
dbch_size - 结构大小的字节值.
dbch_devicetype - 设备类型, 例如 $DBT_DEVTYP_VOLUME - 逻辑分区
$DBT_DEVTYP_OEM = 0x00000000 ; OEM 定义的设备类型
$DBT_DEVTYP_DEVNODE = 0x00000001 ; 设备节点数
$DBT_DEVTYP_VOLUME = 0x00000002; 逻辑分区
$DBT_DEVTYP_PORT = 0x00000003 ; 串口, 并口
$DBT_DEVTYP_NET = 0x00000004 ; 网络资源
dbch_reserved - 保留, 未使用
或 $DEV_BROADCAST_VOLUME 结构, 如果 dbch_devicetype 返回 $DBT_DEVTYP_VOLUME
dbch_size - 结构大小的字节值.
dbch_devicetype - 设备类型 (和上述相同)
dbch_reserved - 保留, 未使用
dbcv_unitmask - 位掩码匹配数 (bits) 与一个驱动器盘符:
0 = A
1 = B
...
26 = Z
dbcv_flags - 标志
要跟踪所有 dbch_devicetype, 该值应等于 $DBT_DEVTYP_DEVICEINTERFACE, 并包括 $DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 接收有关设备更改的所有消息.
afan 发表于 2022-3-10 21:22
WM_DEVICECHANGE连接或断开设备时发送此消息.参 数这些参数被传递到系统.
A大不好意思,之前没接触过 GUIRegisterMsg 这个函数
我自己研究了一下是把 $lParam=$DBT_DEVTYP_PORT 代入嘛?感觉不太对啊 ,能不能帮忙举个例子,我返回的还是16进制的参数:face (9): 要查 $DEV_BROADCAST_HDR 和 $DEV_BROADCAST_PORT 结构
https://docs.microsoft.com/zh-cn/windows/win32/api/dbt/ns-dbt-dev_broadcast_hdr
https://docs.microsoft.com/en-us/windows/win32/api/dbt/ns-dbt-dev_broadcast_port_a
大致就是用 DllStructCreate 创建以上结构,DllStructGetData 获取数据
我这没测试条件… afan 发表于 2022-3-10 23:22
要查 $DEV_BROADCAST_HDR 和 $DEV_BROADCAST_PORT 结构
https://docs.microsoft.com/zh-cn/windows/win32/ ...
再次感谢A大,我来好好研究研究 ,从来没搞过这个。。。:face (32): itzyx 发表于 2022-3-10 23:27
再次感谢A大,我来好好研究研究 ,从来没搞过这个。。。
帮助文档就有此类操作,你可以对照参考再修改
; rasim
; http://www.autoitscript.com/forum/topic/79460-usbmon/
#include <GUIConstantsEx.au3>
Global Const $WM_DEVICECHANGE = 0x0219
Global Const $DBT_DEVICEARRIVAL = 0x8000 ; 查找新设备
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; 禁用设备
Global Const $DBT_DEVTYP_VOLUME = 0x00000002 ; 逻辑驱动器
Global $k = 0
$Gui = GUICreate("WM_DEVICECHANGE", 370, 140)
GUICtrlCreateLabel('连接或断开设备时发送 WM_DEVICECHANGE 消息.' & @CRLF & @CRLF & '请尝试插/拔 USB 闪存驱动器, 并查看托盘提示.', 5, 5, 360, 70)
GUISetState()
GUIRegisterMsg($WM_DEVICECHANGE, "WM_DEVICECHANGE")
Do
Until GUIGetMsg() = -3
Func WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
$k += 1
WinSetTitle($Gui, '', '消息发生次数: ' & $k)
If ($wParam = $DBT_DEVICEARRIVAL) Or ($wParam = $DBT_DEVICEREMOVECOMPLETE) Then
Local $DEV_BROADCAST_VOLUME = DllStructCreate("int dbcvsize;int dbcvdevicetype;int dbcvreserved;int dbcvunitmask;" & _
"ushort dbcvflags", $lParam)
Local $iDriveType = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvdevicetype")
Else
Return $GUI_RUNDEFMSG
EndIf
; 如果该设备不是一个逻辑驱动器, 消息函数返回 $GUI_RUNDEFMSG
If $iDriveType <> $DBT_DEVTYP_VOLUME Then Return $GUI_RUNDEFMSG
Local $iMask = DllStructGetData($DEV_BROADCAST_VOLUME, "dbcvunitmask")
$iMask = Log($iMask) / Log(2)
Local $iDrive = Chr(65 + $iMask) & ":"
Switch $wParam
Case $DBT_DEVICEARRIVAL ; 检测设备
TrayTip("WM_DEVICECHANGE", "设备被连接", 5, 1)
Case $DBT_DEVICEREMOVECOMPLETE ; 关闭设备
TrayTip("WM_DEVICECHANGE", "设备被禁用", 5, 2)
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc
afan 发表于 2022-3-10 23:36
帮助文档就有此类操作,你可以对照参考再修改
A大你推荐的方法肯定能解决,但现在的我弄明白 确实有点伤脑筋,看了半天都没搞对,我着急测试用,我在论坛找了一个例子改了一下:
Local $Ports=''
$objWMIService = objget("WinMgmts:")
$colBios = $objWMIService.ExecQuery("Select * fromWin32_PNPEntity")
For $object in $colBios
$Ports &= StringMid($object.Caption,1)& @CRLF
Next
Local $Bports = StringRegExp($Ports,'(?m).+\(COM\d+\)$', 3)
这样列举 正则筛选也能获得端口的名称。
然后我的想法是,用 GUIRegisterMsg 函数检测到有USB插入后,列举一下所有的端口,再排除原有的端口名称,就是我插入的USB名称,但想法是好的,我再次 $objWMIService.ExecQuery("Select * fromWin32_PNPEntity") 一直报错,错误——变量类型必须为“Object”,百度也找不到方法,实在没办法只能硬着头皮再咨询A大你了。。。。。 试试
Func My_Message_Test($hWnd, $Msg, $WParam, $LParam)
Switch $WParam
Case $DBT_DEVICEARRIVAL, $DBT_DEVICEREMOVECOMPLETE
Local $dbhdr = DllStructCreate('DWORD size;DWORD devicetype;DWORD reserved', $LParam)
If DllStructGetData($dbhdr, "devicetype") = $DBT_DEVTYP_PORT Then
Local $dbport = DllStructCreate('DWORD size;DWORD devicetype;DWORD reserved;char name', $LParam)
MsgBox(0, '', DllStructGetData($dbport, 'name'))
EndIf
EndSwitch
EndFunc ;==>My_Message_Test afan 发表于 2022-3-11 21:50
试试
貌似不行,提示$DBT_DEVTYP_PORT 未声明,我声明以后 虽然成功运行了 但是端口结果显示 C 本帖最后由 afan 于 2022-3-11 22:46 编辑
itzyx 发表于 2022-3-11 22:03
貌似不行,提示$DBT_DEVTYP_PORT 未声明,我声明以后 虽然成功运行了 但是端口结果显示 C
msgbox 改一下显示试试
ConsoleWrite(DllStructGetData($dbport, 'name') & @CRLF)
afan 发表于 2022-3-11 22:14
Local $dbport = DllStructCreate('DWORD size;DWORD devicetype;DWORD reserved;char name', $LPar ...
变成0了。。。
itzyx 发表于 2022-3-11 22:26
变成0了。。。
char name
改成
wchar name itzyx 发表于 2022-3-11 22:26
变成0了。。。
上面改了一下试试 本帖最后由 afan 于 2022-3-11 22:49 编辑
haijie1223 发表于 2022-3-11 22:46
char name
改成
wchar name
应该是这个原因了……虽不是计算出来的size,但128也够了 本帖最后由 itzyx 于 2022-3-11 22:55 编辑
haijie1223 发表于 2022-3-11 22:46
char name
改成
wchar name
可以了 可以了 卧槽6666
页:
[1]
2