- 讀取有沒有文件被復制或剪切
import win32clipboard a = "" clip = win32clipboard.RegisterClipboardFormat("Preferred DropEffect") #返回的clip 就是我們將要代入GetClipboardData函數的該數據結構的代碼 if win32clipboard.OpenClipboard() == None: try: #嘗試以文件的格式讀取剪貼板內容 clip_ = win32clipboard.GetClipboardData(win32clipboard.CF_HDROP) if clip_ != None: #獲取標志位 a = win32clipboard.GetClipboardData(clip) finally: win32clipboard.CloseClipboard() if a[0] == 2: print("剪切") elif a[0] == 5: print("復制") else: print(a[0])
關於“clip = win32clipboard.RegisterClipboardFormat("Preferred DropEffect")”,其中Preferred DropEffect是系統定義的一個關於如何處理文件(復制,移動等)的剪貼板格式字符串,我們在這里同樣注冊這個,不會與系統發生沖突,重復注冊也只是會返回第一次注冊的句柄值;收到這篇博客的啟發:傳送門:如何與資源管理器互動剪切/拷貝/粘貼文件_xuyongbeijing2008的專欄-CSDN博客
我做了更詳細的測試:
#這些函數相關的作用,請參考:http://timgolden.me.uk/pywin32-docs/win32clipboard.html
import win32clipboard
win32clipboard.OpenClipboard() format = 0 str_list = [] try: while True: ret = win32clipboard.EnumClipboardFormats(format) #獲取當前剪貼板上的數據格式 if ret == 0: print("ret={}".format(ret)) break ret_str = win32clipboard.GetClipboardFormatName(ret) #以字符串形式返回格式名稱 print("format={}\tstring={}".format(format,ret_str)) conten_str = win32clipboard.GetClipboardData(ret) #獲取數據 print("\t{}".format(conten_str)) str_list.append(conten_str) format = ret except Exception as e: ctypes.GetLastError() finally: win32clipboard.CloseClipboard()
這是在文件資源管理器上做了剪切文件的操作在運行代碼的輸出:
format=0 string=DataObject
format=49161 string=Shell IDList Array
b"\x01\x00\x00\x00\x0c\x00\x00\x00\x15\x01\x00\x00\x14\x00\x1fP\xe0O\xd0 \xea:i\x10\xa2\xd8\x08\x00+00\x9d\x19\x00/D:\\\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x001\x00\x00\x00\x00\x009T\xaa<\x10\x00python\x00\x00>\x00\t\x00\x04\x00\xef\xbe9T\xa1<9T\xaa<.\x00\x00\x00\xca\x01\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xef\x0f\x00p\x00y\x00t\x00h\x00o\x000\x00\xac)\x9c\x00p\x00y\x00t\x00h\x00o\x00n\x00_\x00c\x00l\x00a\x00s\x00s\x00_\x00e\x00v\x00e\x00r\x00y\x00t\x00h\x00i\x00n\x00g\x00\x00\x00&\x00\x00\x00\x84\x002\x00%\x04\x00\x00OT\xf7L \x00python_everything.spec\x00\x00^\x00\t\x00\x04\x00\xef\xbeJT\xc1AOT\xf7L.\x00\x00\x00:\n\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xd9j\x00p\x00y\x00t\x00h\x00o\x00n\x00_\x00e\x00v\x00e\x00r\x00y\x00t\x00h\x00i\x00n\x00g\x00.\x00s\x00p\x00e\x00c\x00\x00\x00&\x00\x00\x00"
format=49390 string=DataObjectAttributes
format=50001 string=DataObjectAttributesRequiringElevation
b'0\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
format=50000 string=Shell Object Offsets
b'I\x04\x00\x00\x17\x03\x00\x00'
format=49391 string=Preferred DropEffect
b'\x02\x00\x00\x00'
format=49399 string=AsyncFlag
b'\x01\x00\x00\x00'
- 實現復制文件操作,復制操作可以不用設置標志位
#參考:https://chowdera.com/2021/10/20211031055535475l.html #這其實是一個結構體,用以記錄文件的各種信息。 class DROPFILES(ctypes.Structure): _fields_ = [ ("pFiles", ctypes.c_uint), ("x", ctypes.c_long), ("y", ctypes.c_long), ("fNC", ctypes.c_int), ("fWide", ctypes.c_bool), ] pDropFiles = DROPFILES() pDropFiles.pFiles = ctypes.sizeof(DROPFILES) pDropFiles.fWide = True a = bytes(pDropFiles) #獲取文件絕對路徑 filepaths_list = [文件路徑1,文件路徑2,] files = ("\0".join(filepaths_list)).replace("/", "\\") data = files.encode("U16")[2:] + b"\0\0" #結尾一定要兩個\0\0字符,這是規定! ''' 對於多個文本路徑,我們如何將其轉換為我們需要的Unicode 雙字節形式呢? 首先,我們要知道Unicode編碼采用UCS-2格式直接存儲,而UTF-16恰好對應於UCS-2的,即UCS-2指定的碼位通過大端或小端的方式直接保存。UTF-16 有三種類型:UTF-16,UTF-16BE(大端序),UTF-16LE(小端序).UTF-16 通過以名稱BOM(字節順序標記,U + FEFF)啟動文件來指示該文件仍然是小端序。 我們只需要把python String使用UTF-16編碼后,去掉前兩個字節,得到相應的Unicode雙字節。 ''' win32clipboard.OpenClipboard() #打開剪貼板(獨占) try: #若要將信息放在剪貼板上,首先需要使用 EmptyClipboard 函數清除當前的剪貼板內容 win32clipboard.EmptyClipboard() #清空當前的剪貼板信息 win32clipboard.SetClipboardData(win32clipboard.CF_HDROP,bytes(pDropFiles)+data) #設置當前剪貼板數據 except Exception as e: print(str(e)) finally: win32clipboard.CloseClipboard() #無論什么情況,都關閉剪貼板
- 實現剪切文件
#這其實是一個結構體,用以記錄文件的各種信息。 class DROPFILES(ctypes.Structure): _fields_ = [ ("pFiles", ctypes.c_uint), ("x", ctypes.c_long), ("y", ctypes.c_long), ("fNC", ctypes.c_int), ("fWide", ctypes.c_bool), #指示文件是否包含 ANSI 或 Unicode 字符。如果值為零,則文件包含 ANSI 字符。否則,它包含 Unicode 字符。 ] pDropFiles = DROPFILES() pDropFiles.pFiles = ctypes.sizeof(DROPFILES) pDropFiles.fWide = True #獲取文件絕對路徑 filepaths_list = [] files = ("\0".join(filepaths_list)).replace("/", "\\") data = files.encode("U16")[2:] + b"\0\0" #結尾一定要兩個\0\0字符,這是規定!就是構造NULL字符 ''' 對於多個文本路徑,我們如何將其轉換為我們需要的Unicode 雙字節形式呢? 首先,我們要知道Unicode編碼采用UCS-2格式直接存儲,而UTF-16恰好對應於UCS-2的,即UCS-2指定的碼位通過大端或小端的方式直接保存。UTF-16 有三種類型:UTF-16,UTF-16BE(大端序),UTF-16LE(小端序).UTF-16 通過以名稱BOM(字節順序標記,U + FEFF)啟動文件來指示該文件仍然是小端序。 我們只需要把python String使用UTF-16編碼后,去掉前兩個字節,得到相應的Unicode雙字節。 ''' win32clipboard.OpenClipboard() #打開剪貼板(獨占) try: #若要將信息放在剪貼板上,首先需要使用 EmptyClipboard 函數清除任何以前的剪貼板內容 win32clipboard.EmptyClipboard() #清空當前的剪貼板信息,否則不能寫入 uDropEffect = win32clipboard.RegisterClipboardFormat("Preferred DropEffect") #注冊格式 win32clipboard.SetClipboardData(win32clipboard.CF_HDROP,bytes(pDropFiles)+data) #設置當前剪貼板數據 win32clipboard.SetClipboardData(uDropEffect,b'\x02\x00\x00\x00') #寫入代表剪切操作的數據 err = ctypes.windll.kernel32.GetLastError() if err == 0: self.__statusBar.config(text="剪切成功!", fg="green") else: self.__statusBar.config(text="剪切失敗!errorCode={}".format(err), fg="red") except Exception as e: exc_type, exc_value, exc_traceback_obj = sys.exc_info() traceback.print_tb(exc_traceback_obj) self.__statusBar.config(text="剪切失敗!", fg="red") finally: win32clipboard.CloseClipboard() #無論什么情況,都關閉剪貼板