Python编程:局域网U盘/硬盘连接记录系统

Python 获取 USB 设备信息

在 Python 中,有几种方法可以获取连接到计算机的 USB 设备信息。以下是几种常用的方法:

方法一:使用 pyusb 库

import usb.core
import usb.util

# 列出所有 USB 设备
devices = usb.core.find(find_all=True)

for device in devices:
    print(f"设备: {device}")
    print(f"ID: {hex(device.idVendor)}:{hex(device.idProduct)}")
    print(f"制造商: {usb.util.get_string(device, device.iManufacturer)}")
    print(f"产品: {usb.util.get_string(device, device.iProduct)}")
    print("-" * 40)

安装 pyusb:

pip install pyusb

方法二:使用 psutil 库(跨平台)

import psutil

# 获取所有 USB 设备
usb_devices = [d for d in psutil.disk_partitions() if 'removable' in d.opts]

for device in usb_devices:
    print(f"设备: {device.device}")
    print(f"挂载点: {device.mountpoint}")
    print(f"文件系统类型: {device.fstype}")
    print(f"选项: {device.opts}")
    print("-" * 40)

安装 psutil:

pip install psutil

方法三:在 Windows 上使用 WMI

import wmi

c = wmi.WMI()

# 获取 USB 设备
for device in c.Win32_USBControllerDevice():
    print(f"设备ID: {device.Dependent.PNPDeviceID}")
    print(f"描述: {device.Dependent.Description}")
    print(f"状态: {device.Dependent.Status}")
    print("-" * 40)

安装 WMI:

pip install wmi

方法四:在 Linux 上使用 lsusb 命令

import subprocess

result = subprocess.run(['lsusb'], stdout=subprocess.PIPE)
print(result.stdout.decode('utf-8'))

方法五:使用 platform-specific 方法

Windows 版本

import winreg

def get_usb_devices():
    devices = []
    reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
    key = winreg.OpenKey(reg, r"SYSTEM\CurrentControlSet\Enum\USB")
    
    for i in range(winreg.QueryInfoKey(key)[0]):
        subkey_name = winreg.EnumKey(key, i)
        subkey = winreg.OpenKey(key, subkey_name)
        
        for j in range(winreg.QueryInfoKey(subkey)[0]):
            subsubkey_name = winreg.EnumKey(subkey, j)
            devices.append(f"{subkey_name}\\{subsubkey_name}")
    
    return devices

usb_devices = get_usb_devices()
for device in usb_devices:
    print(device)

Linux 版本

import os

def get_usb_devices():
    return [d for d in os.listdir('/dev') if d.startswith('sd')]

usb_devices = get_usb_devices()
print("连接的USB存储设备:", usb_devices)

方法六:使用 pyudev (Linux)

import pyudev

context = pyudev.Context()
for device in context.list_devices(subsystem='usb'):
    print(f"设备: {device.device_node}")
    print(f"厂商ID: {device.get('ID_VENDOR_ID')}")
    print(f"产品ID: {device.get('ID_MODEL_ID')}")
    print(f"厂商: {device.get('ID_VENDOR')}")
    print(f"产品: {device.get('ID_MODEL')}")
    print("-" * 40)

安装 pyudev:

pip install pyudev

局域网U盘/硬盘连接记录系统

下面提供一个完整的解决方案,包含PyQt图形界面、客户端和服务器功能。这个系统将允许用户通过图形界面查看所有局域网内主机的U盘/硬盘连接记录。

系统架构

  1. 服务器端:接收并存储所有客户端的USB连接记录

  2. 客户端:监控本地USB设备变化并上报服务器

  3. 管理界面:PyQt实现的GUI,用于查看和分析记录

完整代码实现

1. 服务器端 (带PyQt界面)

# server_gui.py
import sys
import socket
import sqlite3
from datetime import datetime
import threading
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QTableWidget, QTableWidgetItem, 
                            QLabel, QPushButton, QComboBox, QLineEdit)
from PyQt5.QtCore import QTimer, Qt

class USBServerGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("USB设备连接监控服务器")
        self.setGeometry(100, 100, 800, 600)
        
        self.create_database()
        self.init_ui()
        self.start_server()
        
    def create_database(self):
        self.conn = sqlite3.connect('usb_logs.db')
        self.c = self.conn.cursor()
        self.c.execute('''CREATE TABLE IF NOT EXISTS usb_connections
                         (id INTEGER PRIMARY KEY AUTOINCREMENT,
                         host_ip TEXT,
                         host_name TEXT,
                         device_name TEXT,
                         device_serial TEXT,
                         connection_time DATETIME,
                         event_type TEXT)''')
        self.conn.commit()
        
    def init_ui(self):
        main_widget = QWidget()
        layout = QVBoxLayout()
        
        # 控制面板
        control_panel = QWidget()
        control_layout = QHBoxLayout()
        
        self.status_label = QLabel("服务器状态: 运行中")
        self.refresh_btn = QPushButton("刷新数据")
        self.refresh_btn.clicked.connect(self.load_data)
        
        self.filter_host = QComboBox()
        self.filter_host.addItem("所有主机")
        self.filter_host.currentTextChanged.connect(self.load_data)
        
        self.filter_event = QComboBox()
        self.filter_event.addItem("所有事件")
        self.filter_event.addItem("已连接")
        self.filter_event.addItem("已断开")
        self.filter_event.currentTextChanged.connect(self.load_data)
        
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("搜索设备名称或序列号...")
        self.search_input.textChanged.connect(self.load_data)
        
        control_layout.addWidget(self.status_label)
        control_layout.addWidget(QLabel("筛选主机:"))
        control_layout.addWidget(self.filter_host)
        control_layout.addWidget(QLabel("筛选事件:"))
        control_layout.addWidget(self.filter_event)
        control_layout.addWidget(QLabel("搜索:"))
        control_layout.addWidget(self.search_input)
        control_layout.addWidget(self.refresh_btn)
        control_panel.setLayout(control_layout)
        
        # 数据表格
        self.table = QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels(["ID", "主机名", "IP地址", "设备名称", "事件类型", "连接时间"])
        self.table.setColumnWidth(0, 50)
        self.table.setColumnWidth(1, 150)
        self.table.setColumnWidth(2, 120)
        self.table.setColumnWidth(3, 200)
        self.table.setColumnWidth(4, 80)
        self.table.setColumnWidth(5, 150)
        
        layout.addWidget(control_panel)
        layout.addWidget(self.table)
        
        main_widget.setLayout(layout)
        self.setCentralWidget(main_widget)
        
        # 定时刷新数据
        self.timer = QTimer()
        self.timer.timeout.connect(self.load_data)
        self.timer.start(5000)  # 5秒刷新一次
        
        # 初始加载数据
        self.load_data()
        
    def load_data(self):
        host_filter = self.filter_host.currentText()
        event_filter = self.filter_event.currentText()
        search_text = self.search_input.text().strip()
        
        query = "SELECT id, host_name, host_ip, device_name, event_type, connection_time FROM usb_connections"
        conditions = []
        
        if host_filter != "所有主机":
            conditions.append(f"host_name = '{host_filter}'")
            
        if event_filter != "所有事件":
            conditions.append(f"event_type = '{event_filter.lower()}'")
            
        if search_text:
            conditions.append(f"(device_name LIKE '%{search_text}%' OR device_serial LIKE '%{search_text}%')")
            
        if conditions:
            query += " WHERE " + " AND ".join(conditions)
            
        query += " ORDER BY connection_time DESC"
        
        self.c.execute(query)
        data = self.c.fetchall()
        
        self.table.setRowCount(len(data))
        for row_idx, row_data in enumerate(data):
            for col_idx, col_data in enumerate(row_data):
                item = QTableWidgetItem(str(col_data))
                item.setFlags(item.flags() ^ Qt.ItemIsEditable)
                self.table.setItem(row_idx, col_idx, item)
                
        # 更新主机筛选列表
        self.update_host_list()
        
    def update_host_list(self):
        current_host = self.filter_host.currentText()
        self.filter_host.clear()
        self.filter_host.addItem("所有主机")
        
        self.c.execute("SELECT DISTINCT host_name FROM usb_connections ORDER BY host_name")
        hosts = [host[0] for host in self.c.fetchall()]
        
        for host in hosts:
            self.filter_host.addItem(host)
            
        # 恢复之前的选择
        if current_host in [self.filter_host.itemText(i) for i in range(self.filter_host.count())]:
            self.filter_host.setCurrentText(current_host)
            
    def start_server(self):
        self.server_thread = threading.Thread(target=self.run_server, daemon=True)
        self.server_thread.start()
        
    def run_server(self):
        host = '0.0.0.0'
        port = 65432
        
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((host, port))
            s.listen()
            
            while True:
                conn, addr = s.accept()
                client_thread = threading.Thread(
                    target=self.handle_client, 
                    args=(conn, addr),
                    daemon=True
                )
                client_thread.start()
                
    def handle_client(self, conn, addr):
        try:
            while True:
                data = conn.recv(1024).decode('utf-8')
                if not data:
                    break
                
                parts = data.split('|')
                if len(parts) == 4:
                    host_name, device_name, serial, event_type = parts
                    
                    self.c.execute(
                        "INSERT INTO usb_connections (host_ip, host_name, device_name, device_serial, connection_time, event_type) VALUES (?, ?, ?, ?, ?, ?)",
                        (addr[0], host_name, device_name, serial, datetime.now(), event_type)
                    )
                    self.conn.commit()
                    
        except Exception as e:
            print(f"Error with {addr}: {e}")
        finally:
            conn.close()
            
    def closeEvent(self, event):
        self.conn.close()
        event.accept()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = USBServerGUI()
    window.show()
    sys.exit(app.exec_())

2. 客户端 (带PyQt界面)

# client_gui.py
import sys
import socket
import platform
import getpass
import time
import winreg
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QLabel, QPushButton, QTextEdit, QLineEdit)
from PyQt5.QtCore import QTimer, Qt

class USBClientGUI(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("USB设备监控客户端")
        self.setGeometry(100, 100, 500, 400)
        
        self.server_ip = "192.168.1.100"  # 默认服务器IP
        self.host_name = platform.node()
        self.last_devices = set()
        
        self.init_ui()
        self.start_monitoring()
        
    def init_ui(self):
        main_widget = QWidget()
        layout = QVBoxLayout()
        
        # 服务器设置
        server_panel = QWidget()
        server_layout = QHBoxLayout()
        
        server_layout.addWidget(QLabel("服务器IP:"))
        self.server_input = QLineEdit(self.server_ip)
        self.apply_btn = QPushButton("应用")
        self.apply_btn.clicked.connect(self.update_server_ip)
        
        server_layout.addWidget(self.server_input)
        server_layout.addWidget(self.apply_btn)
        server_panel.setLayout(server_layout)
        
        # 状态显示
        self.status_label = QLabel("状态: 正在监控USB设备...")
        self.log_area = QTextEdit()
        self.log_area.setReadOnly(True)
        
        # 控制按钮
        self.toggle_btn = QPushButton("暂停监控")
        self.toggle_btn.clicked.connect(self.toggle_monitoring)
        
        layout.addWidget(server_panel)
        layout.addWidget(self.status_label)
        layout.addWidget(self.log_area)
        layout.addWidget(self.toggle_btn)
        
        main_widget.setLayout(layout)
        self.setCentralWidget(main_widget)
        
        # 监控定时器
        self.monitor_timer = QTimer()
        self.monitor_timer.timeout.connect(self.check_usb_devices)
        self.monitor_timer.start(3000)  # 3秒检查一次
        
    def update_server_ip(self):
        new_ip = self.server_input.text().strip()
        if new_ip:
            self.server_ip = new_ip
            self.log(f"服务器IP已更新为: {self.server_ip}")
            
    def toggle_monitoring(self):
        if self.monitor_timer.isActive():
            self.monitor_timer.stop()
            self.toggle_btn.setText("开始监控")
            self.status_label.setText("状态: 监控已暂停")
            self.log("USB设备监控已暂停")
        else:
            self.monitor_timer.start(3000)
            self.toggle_btn.setText("暂停监控")
            self.status_label.setText("状态: 正在监控USB设备...")
            self.log("USB设备监控已恢复")
            
    def log(self, message):
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        self.log_area.append(f"[{timestamp}] {message}")
        
    def start_monitoring(self):
        self.log(f"USB设备监控客户端已启动 (主机名: {self.host_name})")
        self.log(f"正在连接服务器: {self.server_ip}")
        
    def check_usb_devices(self):
        try:
            current_devices = set()
            
            if platform.system() == 'Windows':
                try:
                    reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
                    key = winreg.OpenKey(reg, r"SYSTEM\CurrentControlSet\Enum\USBSTOR")
                    
                    for i in range(winreg.QueryInfoKey(key)[0]):
                        subkey_name = winreg.EnumKey(key, i)
                        subkey = winreg.OpenKey(key, subkey_name)
                        
                        for j in range(winreg.QueryInfoKey(subkey)[0]):
                            subsubkey_name = winreg.EnumKey(subkey, j)
                            subsubkey = winreg.OpenKey(subkey, subsubkey_name)
                            
                            try:
                                device_name = winreg.QueryValueEx(subsubkey, "FriendlyName")[0]
                                device_serial = subsubkey_name.split('&')[0]
                                current_devices.add((device_name, device_serial))
                            except WindowsError:
                                continue
                except WindowsError:
                    pass
            
            # 检测新设备
            new_devices = current_devices - self.last_devices
            for device in new_devices:
                self.log(f"检测到新设备: {device[0]} (序列号: {device[1]})")
                self.send_usb_event(device[0], device[1], 'connected')
            
            # 检测移除的设备
            removed_devices = self.last_devices - current_devices
            for device in removed_devices:
                self.log(f"设备已移除: {device[0]} (序列号: {device[1]})")
                self.send_usb_event(device[0], device[1], 'disconnected')
            
            self.last_devices = current_devices
        except Exception as e:
            self.log(f"监控错误: {str(e)}")
            
    def send_usb_event(self, device_name, device_serial, event_type):
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.connect((self.server_ip, 65432))
                data = f"{self.host_name}|{device_name}|{device_serial}|{event_type}"
                s.sendall(data.encode('utf-8'))
        except Exception as e:
            self.log(f"无法连接到服务器: {str(e)}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = USBClientGUI()
    window.show()
    sys.exit(app.exec_())

部署说明

  1. 服务器端部署:

    • 在一台始终在线的机器上运行server_gui.py

    • 确保防火墙允许65432端口的TCP连接

    • 界面将显示所有客户端的USB连接记录

  2. 客户端部署:

    • 在所有需要监控的Windows机器上安装client_gui.py

    • 修改默认服务器IP为实际服务器IP

    • 可以设置为开机启动

  3. 功能特点:

    • 服务器端实时显示所有USB连接事件

    • 支持按主机名、事件类型筛选

    • 支持关键词搜索

    • 客户端可暂停/恢复监控

    • 客户端可修改服务器IP

功能迭代

  1. 安全性增强:

    • 添加客户端认证机制

    • 使用SSL加密通信

  2. 功能扩展:

    • 添加邮件/短信通知功能

    • 实现数据导出(Excel, CSV)

    • 添加图表统计功能

  3. 跨平台支持:

    • 添加Linux/macOS的USB监控实现

  4. 安装程序:

    • 使用PyInstaller打包为可执行文件

    • 创建安装程序包

这个完整实现提供了图形化的监控解决方案,适合企业或组织内部使用,可以有效监控局域网内所有主机的USB设备连接情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值