当前位置: 首页 > 面试题库 >

在Windows上检测插入的USB

寿元白
2023-03-14
问题内容

我目前正在用python编写一个安全程序,该程序在主机上作为守护程序运行。每当检测到USB存储设备时,它都会将所有文件从USB复制到主机上的某个目录中。有什么简单的方法可以进行这种USB检测/接口?提前致谢!


问题答案:

是的,您需要使用RegisterDeviceNotificationWindows
API调用。据我所知,没有包装此功能的Python模块,因此您必须使用它ctypes来调用此功能。

幸运的是,您不是第一个想要这样做的人,因此网上有一些代码示例。WxPython提供了一个代码示例,但是当您编写守护程序时,您可能对此并不感兴趣。您可能想尝试下面的代码示例,该示例依赖于ctypespywin32,从Tim
Golden
毫不客气地进行了研究:

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)


 类似资料:
  • 我想从我的学生表中检索最后插入的id并传递到视图。但我不知道怎么做?我使用以下代码在表中插入数据。 有人能帮帮我吗?

  • 我想识别在UserControl内的TextBox上按下的Ctrl+e键,因为这是使用textbox_KeyDown(对象发送者,KeyEventArgs e)事件并检查以下条件 有人能帮帮我吗。提前致谢

  • 我正在一台新的Windows10笔记本电脑上设置一个Android开发环境。我在使用其他操作系统的其他机器上已经这样做过很多次了,但这是第一次使用Windows10。问题是,Android Studio无法检测我的设备(LG区域3)后,我通过USB连接它。请注意,我以前曾在Arch Linux桌面上使用此设备进行开发。 我已经下载了Android Studio并创建了几个AVD。我可以运行我的应用

  • 问题内容: 我已经为嵌入式Linux项目编写了一个应用程序,并且希望用户插入USB驱动器时,我的应用程序显示特定菜单。我正在用Qt用C ++编写应用程序。 我的系统没有d-bus,但使用的是udev。在我看来,udev是执行此检测的“正确”方法,但似乎很复杂。 谁能指出我正确的方向来开始这一工作?有没有udev的方法吗?如果没有,是否可以使用udev的“入门”指南?我真的不需要太多功能,只需一种方

  • 我似乎无法让DevTools设备功能在我的三星Galaxy S4上运行,即使遵循了中概述的步骤https://developers.google.com/chrome-developer-tools/docs/remote-debugging 我的设备有Chrome v32和Chrome Beta v33,而我的电脑有Chrome v33和Chrome Canary v35。 已在我的设备上启用U

  • 问题内容: 我尝试使用谷歌搜索答案,但是发现的只是关于如何从浏览器中检测Java的技巧,或者只是启动Java并查看其是否运行的一种非常通用的方法,这可能会延长我的应用程序的运行时间。(〜在我的机器上第一次启动时约两秒钟) 如果有以下限制,我希望有一种更快的方法: 仅Sun / Oracle JRE或JDK 只有1.6或更高 仅Windows平台 不是 来自浏览器,而是来自普通的旧Win32可执行文