使用 python 在 Windows 10 上检测 USB 设备插入 [英] Detecting USB Device Insertion on Windows 10 using python

查看:124
本文介绍了使用 python 在 Windows 10 上检测 USB 设备插入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法获得以下代码用于检测 USB 设备插入 使用 Python 3.7 在我的 Windows 10(64 位)计算机上工作.

I can't get the following code for Detecting USB Device Insertion to work on my Windows 10 (64 bit) computer with Python 3.7.

import win32serviceutil
import win32service
import win32event
import servicemanager

import win32gui
import win32gui_struct
struct = win32gui_struct.struct
pywintypes = win32gui_struct.pywintypes
import win32con

GUID_DEVINTERFACE_USB_DEVICE = "{A5DCBF10-6530-11D2-901F-00C04FB951ED}"
DBT_DEVICEARRIVAL = 0x8000
DBT_DEVICEREMOVECOMPLETE = 0x8004

import ctypes

#
# Cut-down clone of UnpackDEV_BROADCAST from win32gui_struct, to be
# used for monkey-patching said module with correct handling
# of the "name" param of DBT_DEVTYPE_DEVICEINTERFACE
#
def _UnpackDEV_BROADCAST (lparam):
  if lparam == 0: return None
  hdr_format = "iii"
  hdr_size = struct.calcsize (hdr_format)
  hdr_buf = win32gui.PyGetMemory (lparam, hdr_size)
  size, devtype, reserved = struct.unpack ("iii", hdr_buf)
  # Due to x64 alignment issues, we need to use the full format string over
  # the entire buffer.  ie, on x64:
  # calcsize('iiiP') != calcsize('iii')+calcsize('P')
  buf = win32gui.PyGetMemory (lparam, size)

  extra = {}
  if devtype == win32con.DBT_DEVTYP_DEVICEINTERFACE:
    fmt = hdr_format + "16s"
    _, _, _, guid_bytes = struct.unpack (fmt, buf[:struct.calcsize(fmt)])
    extra['classguid'] = pywintypes.IID (guid_bytes, True)
    extra['name'] = ctypes.wstring_at (lparam + struct.calcsize(fmt))
  else:
    raise NotImplementedError("unknown device type %d" % (devtype,))
  return win32gui_struct.DEV_BROADCAST_INFO(devtype, **extra)
win32gui_struct.UnpackDEV_BROADCAST = _UnpackDEV_BROADCAST

class DeviceEventService (win32serviceutil.ServiceFramework):

  _svc_name_ = "DevEventHandler"
  _svc_display_name_ = "Device Event Handler"
  _svc_description_ = "Handle device notification events"

  def __init__(self, args):
    win32serviceutil.ServiceFramework.__init__ (self, args)
    self.hWaitStop = win32event.CreateEvent (None, 0, 0, None)
    #
    # Specify that we're interested in device interface
    # events for USB devices
    #
    filter = win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE (
      GUID_DEVINTERFACE_USB_DEVICE
    )
    self.hDevNotify = win32gui.RegisterDeviceNotification (
      self.ssh, # copy of the service status handle
      filter,
      win32con.DEVICE_NOTIFY_SERVICE_HANDLE
    )

  #
  # Add to the list of controls already handled by the underlying
  # ServiceFramework class. We're only interested in device events
  #
  def GetAcceptedControls(self):
    rc = win32serviceutil.ServiceFramework.GetAcceptedControls (self)
    rc |= win32service.SERVICE_CONTROL_DEVICEEVENT
    return rc

  #
  # Handle non-standard service events (including our device broadcasts)
  # by logging to the Application event log
  #
  def SvcOtherEx(self, control, event_type, data):
    if control == win32service.SERVICE_CONTROL_DEVICEEVENT:
      info = win32gui_struct.UnpackDEV_BROADCAST(data)
      #
      # This is the key bit here where you'll presumably
      # do something other than log the event. Perhaps pulse
      # a named event or write to a secure pipe etc. etc.
      #
      if event_type == DBT_DEVICEARRIVAL:
        servicemanager.LogMsg (
          servicemanager.EVENTLOG_INFORMATION_TYPE,
          0xF000,
          ("Device %s arrived" % info.name, '')
        )
      elif event_type == DBT_DEVICEREMOVECOMPLETE:
        servicemanager.LogMsg (
          servicemanager.EVENTLOG_INFORMATION_TYPE,
          0xF000,
          ("Device %s removed" % info.name, '')
        )

  #
  # Standard stuff for stopping and running service; nothing
  # specific to device notifications
  #
  def SvcStop(self):
    self.ReportServiceStatus (win32service.SERVICE_STOP_PENDING)
    win32event.SetEvent (self.hWaitStop)

  def SvcDoRun(self):
    win32event.WaitForSingleObject (self.hWaitStop, win32event.INFINITE)
    servicemanager.LogMsg (
      servicemanager.EVENTLOG_INFORMATION_TYPE,
      servicemanager.PYS_SERVICE_STOPPED,
      (self._svc_name_, '')
    )

if __name__=='__main__':
  win32serviceutil.HandleCommandLine (DeviceEventService)

  1. 我使用以下命令启动脚本:python main.py start

然后在命令提示符中出现以下错误信息:

Then the following error messages appear in the command prompt:

启动服务 DevEventHandler启动服务时出错:访问被拒绝

  1. 然后我以管理员权限运行脚本:runas/user:administrator "python main.py start"

命令提示符中出现另一条错误消息:

Another error messages appear in the command prompt:

启动服务 DevEventHandler启动服务时出错:指定的服务不作为已安装的服务存在.

如何修复指定的服务不作为已安装的服务存在"错误?

How can the 'The specified service does not exist as an installed service' error be fixed?

推荐答案

我使用 Python 3.8.2 x64 进行了测试.

I tested with Python 3.8.2 x64.

  1. 安装pywin32(pip install pywin32)
  2. https://github.com/tjguk 安装 WMI 模块的当前/最新版本 (1.5)/wmi (pip install -e git+https://github.com/tjguk/wmi.git#egg=wmi)
  3. 运行一个脚本(在我的例子中是test.py),比如:
  1. Install pywin32 (pip install pywin32)
  2. Install the current/last version (1.5) of the WMI module from https://github.com/tjguk/wmi (pip install -e git+https://github.com/tjguk/wmi.git#egg=wmi)
  3. run a script (test.py in my case), like:

import wmi

raw_wql = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA \'Win32_USBHub\'"
c = wmi.WMI ()
watcher = c.watch_for(raw_wql=raw_wql)
while 1:
  usb = watcher ()
  print(usb)

  1. 插入 USB 设备.输出看起来像:

(wmi-py) C:\Users\USER\Source\wmi-py>py test.py

instance of Win32_USBHub
{
        Caption = "USB Composite Device";
        ConfigManagerErrorCode = 0;
        ConfigManagerUserConfig = FALSE;
        CreationClassName = "Win32_USBHub";
        Description = "USB Composite Device";
...

非常感谢 WMI 模块作者和 Windows 书呆子的讨论 使用windows服务和c#检测U盘插入和移除

Many thanks to the WMI module author, and the Windows nerds' discussion here Detecting USB drive insertion and removal using windows service and c#

这篇关于使用 python 在 Windows 10 上检测 USB 设备插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆