找回密码
 加入
搜索
查看: 2033|回复: 27

[系统综合] 【已解决】输出的USB参数如何转换成端口名称

[复制链接]
发表于 2022-3-10 21:00:07 | 显示全部楼层 |阅读模式
本帖最后由 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 改成端口名称,如图所示,不知道如何转换,麻烦各位大佬指点一下,万分感谢。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2022-3-11 22:58:35 | 显示全部楼层


我玩了个嘚~~~
发表于 2022-3-10 21:22:26 | 显示全部楼层
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 接收有关设备更改的所有消息.  

评分

参与人数 1金钱 +40 收起 理由
itzyx + 40 感谢A大,我明天去公司试试

查看全部评分

 楼主| 发表于 2022-3-10 21:45:34 | 显示全部楼层
afan 发表于 2022-3-10 21:22
WM_DEVICECHANGE连接或断开设备时发送此消息.参 数这些参数被传递到系统.

A大不好意思,之前没接触过 GUIRegisterMsg 这个函数
我自己研究了一下是把 $lParam=$DBT_DEVTYP_PORT 代入嘛?  感觉不太对啊 ,能不能帮忙举个例子,我返回的还是16进制的参数
发表于 2022-3-10 23:22:28 | 显示全部楼层
要查 $DEV_BROADCAST_HDR 和 $DEV_BROADCAST_PORT 结构
https://docs.microsoft.com/zh-cn ... t-dev_broadcast_hdr
https://docs.microsoft.com/en-us ... ev_broadcast_port_a
大致就是用 DllStructCreate 创建以上结构,DllStructGetData 获取数据
我这没测试条件…
 楼主| 发表于 2022-3-10 23:27:55 | 显示全部楼层
afan 发表于 2022-3-10 23:22
要查 $DEV_BROADCAST_HDR 和 $DEV_BROADCAST_PORT 结构
https://docs.microsoft.com/zh-cn/windows/win32/ ...

再次感谢A大,我来好好研究研究 ,从来没搞过这个。。。
发表于 2022-3-10 23:36:11 | 显示全部楼层
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

评分

参与人数 1金钱 +40 收起 理由
itzyx + 40 &amp;amp;#128076; 帅气!

查看全部评分

 楼主| 发表于 2022-3-11 21:05:42 | 显示全部楼层
afan 发表于 2022-3-10 23:36
帮助文档就有此类操作,你可以对照参考再修改

A大你推荐的方法肯定能解决,但现在的我弄明白 确实有点伤脑筋,看了半天都没搞对,我着急测试用,我在论坛找了一个例子改了一下:
Local $Ports=''
$objWMIService = objget("WinMgmts:")
$colBios = $objWMIService.ExecQuery("Select * from  Win32_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 * from  Win32_PNPEntity") 一直报错,错误——变量类型必须为“Object”,百度也找不到方法,实在没办法只能硬着头皮再咨询A大你了。。。。。
发表于 2022-3-11 21:50:02 | 显示全部楼层
试试
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[128]', $LParam)
                                MsgBox(0, '', DllStructGetData($dbport, 'name'))
                        EndIf
        EndSwitch
EndFunc   ;==>My_Message_Test
 楼主| 发表于 2022-3-11 22:03:39 | 显示全部楼层

貌似不行,提示$DBT_DEVTYP_PORT 未声明,我声明以后 虽然成功运行了 但是端口结果显示 C

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2022-3-11 22:14:16 | 显示全部楼层
本帖最后由 afan 于 2022-3-11 22:46 编辑
itzyx 发表于 2022-3-11 22:03
貌似不行,提示$DBT_DEVTYP_PORT 未声明,我声明以后 虽然成功运行了 但是端口结果显示 C

msgbox 改一下显示试试
ConsoleWrite(DllStructGetData($dbport, 'name') & @CRLF)
 楼主| 发表于 2022-3-11 22:26:52 | 显示全部楼层
afan 发表于 2022-3-11 22:14
Local $dbport = DllStructCreate('DWORD size;DWORD devicetype;DWORD reserved;char name[128]', $LPar ...

变成0了。。。  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2022-3-11 22:46:01 | 显示全部楼层

char name[128]
改成
wchar name[128]

评分

参与人数 1金钱 +40 收起 理由
itzyx + 40 发哥帅气

查看全部评分

发表于 2022-3-11 22:47:08 | 显示全部楼层

上面改了一下试试
发表于 2022-3-11 22:47:57 | 显示全部楼层
本帖最后由 afan 于 2022-3-11 22:49 编辑
haijie1223 发表于 2022-3-11 22:46
char name[128]
改成
wchar name[128]

应该是这个原因了……  虽不是计算出来的size,但128也够了

评分

参与人数 1金钱 +20 收起 理由
itzyx + 20 A大爱死

查看全部评分

 楼主| 发表于 2022-3-11 22:51:01 | 显示全部楼层
本帖最后由 itzyx 于 2022-3-11 22:55 编辑
haijie1223 发表于 2022-3-11 22:46
char name[128]
改成
wchar name[128]

可以了 可以了 卧槽6666
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-3 12:10 , Processed in 0.087953 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表