itzyx 发表于 2022-3-10 21:00:07

【已解决】输出的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 改成端口名称,如图所示,不知道如何转换,麻烦各位大佬指点一下,万分感谢。

haijie1223 发表于 2022-3-11 22:58:35

itzyx 发表于 2022-3-11 22:51
发哥 还是不行

我玩了个嘚~~~

afan 发表于 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 接收有关设备更改的所有消息.

itzyx 发表于 2022-3-10 21:45:34

afan 发表于 2022-3-10 21:22
WM_DEVICECHANGE连接或断开设备时发送此消息.参 数这些参数被传递到系统.

A大不好意思,之前没接触过 GUIRegisterMsg 这个函数
我自己研究了一下是把 $lParam=$DBT_DEVTYP_PORT 代入嘛?感觉不太对啊 ,能不能帮忙举个例子,我返回的还是16进制的参数:face (9):

afan 发表于 2022-3-10 23:22:28

要查 $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 获取数据
我这没测试条件…

itzyx 发表于 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大,我来好好研究研究 ,从来没搞过这个。。。:face (32):

afan 发表于 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

itzyx 发表于 2022-3-11 21:05:42

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大你了。。。。。

afan 发表于 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', $LParam)
                                MsgBox(0, '', DllStructGetData($dbport, 'name'))
                        EndIf
        EndSwitch
EndFunc   ;==>My_Message_Test

itzyx 发表于 2022-3-11 22:03:39

afan 发表于 2022-3-11 21:50
试试

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

afan 发表于 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)

itzyx 发表于 2022-3-11 22:26:52

afan 发表于 2022-3-11 22:14
Local $dbport = DllStructCreate('DWORD size;DWORD devicetype;DWORD reserved;char name', $LPar ...

变成0了。。。

haijie1223 发表于 2022-3-11 22:46:01

itzyx 发表于 2022-3-11 22:26
变成0了。。。

char name
改成
wchar name

afan 发表于 2022-3-11 22:47:08

itzyx 发表于 2022-3-11 22:26
变成0了。。。

上面改了一下试试

afan 发表于 2022-3-11 22:47:57

本帖最后由 afan 于 2022-3-11 22:49 编辑

haijie1223 发表于 2022-3-11 22:46
char name
改成
wchar name
应该是这个原因了……虽不是计算出来的size,但128也够了

itzyx 发表于 2022-3-11 22:51:01

本帖最后由 itzyx 于 2022-3-11 22:55 编辑

haijie1223 发表于 2022-3-11 22:46
char name
改成
wchar name
可以了 可以了 卧槽6666
页: [1] 2
查看完整版本: 【已解决】输出的USB参数如何转换成端口名称