简体   繁体   English

使用 python 将字节复制并粘贴到剪贴板

[英]Copy and paste bytes to clipboard with python

I'm trying to modify the clipboard byte contents, and so far I've managed to make a script that reads the clipboard as bytes:我正在尝试修改剪贴板字节内容,到目前为止,我已经设法制作了一个将剪贴板读取为字节的脚本:

import ctypes

CF_TEXT = 1

kernel32 = ctypes.windll.kernel32
kernel32.GlobalLock.argtypes = [ctypes.c_void_p]
kernel32.GlobalLock.restype = ctypes.c_void_p
kernel32.GlobalUnlock.argtypes = [ctypes.c_void_p]
user32 = ctypes.windll.user32
user32.GetClipboardData.restype = ctypes.c_void_p

def get_clipboard_text():
    user32.OpenClipboard(0)
    try:
        if user32.IsClipboardFormatAvailable(CF_TEXT):
            data = user32.GetClipboardData(CF_TEXT)
            data_locked = kernel32.GlobalLock(data)
            text = ctypes.c_char_p(data_locked)
            value = text.value
            kernel32.GlobalUnlock(data_locked)
            return value
    finally:
        user32.CloseClipboard()

print(get_clipboard_text())

this script reads the clipboard and outputs something like this:此脚本读取剪贴板并输出如下内容:

b'clipboard content here'

Now, I can't seem to find anywhere how to modify and write it back to the clipboard using bytes, pyperclip and many other modules I've tried use strings and has no way of using bytes .现在,我似乎无法在任何地方找到如何使用 bytes、 pyperclip 和我尝试过的许多其他模块修改并将其写回剪贴板,但我尝试过使用 strings 并且无法使用 bytes Any suggestions would be appreciated任何建议,将不胜感激

Here's an example setting clipboard text, but note that CF_TEXT is ANSI text format and must be terminated by a null byte.这是一个设置剪贴板文本的示例,但请注意 CF_TEXT 是 ANSI 文本格式,并且必须以 null 字节终止。 You can't send arbitrary byte data that contains nulls.您不能发送包含空值的任意字节数据。 The example sends bytes 0x01-0xFF as a message and verifies that is what is returned from the clipboard.该示例将字节 0x01-0xFF 作为消息发送,并验证这是从剪贴板返回的内容。

import ctypes
from ctypes import wintypes as w

CF_TEXT = 1
GMEM_MOVEABLE = 2

kernel32 = ctypes.WinDLL('kernel32',use_last_error=True)
kernel32.GlobalAlloc.argtypes = w.UINT,ctypes.c_size_t
kernel32.GlobalAlloc.restype = w.HGLOBAL
kernel32.GlobalLock.argtypes = w.HGLOBAL,
kernel32.GlobalLock.restype = w.LPVOID
kernel32.GlobalUnlock.argtypes = w.HGLOBAL,
kernel32.GlobalUnlock.restype = w.BOOL
kernel32.GetConsoleWindow.argtypes = ()
kernel32.GetConsoleWindow.restype = w.HWND
kernel32.RtlCopyMemory.argtypes = w.LPVOID,w.LPCVOID,ctypes.c_size_t
kernel32.RtlCopyMemory.restype = None

user32 = ctypes.WinDLL('user32',use_last_error=True)
user32.OpenClipboard.argtypes = w.HWND,
user32.OpenClipboard.restype = w.BOOL
user32.CloseClipboard.argtypes = ()
user32.CloseClipboard.restype = w.BOOL
user32.EmptyClipboard.argtypes = ()
user32.EmptyClipboard.restype = w.BOOL
user32.IsClipboardFormatAvailable.argtypes = w.UINT,
user32.IsClipboardFormatAvailable.restype = w.BOOL
user32.GetClipboardData.argtypes = w.UINT,
user32.GetClipboardData.restype = w.HANDLE
user32.SetClipboardData.argtypes = w.UINT,w.HANDLE
user32.SetClipboardData.restype = w.HANDLE
user32.GetActiveWindow.argtypes = ()
user32.GetActiveWindow.restype = w.HWND

def get_clipboard_text():
    user32.OpenClipboard(None)
    try:
        if user32.IsClipboardFormatAvailable(CF_TEXT):
            data = user32.GetClipboardData(CF_TEXT)
            data_locked = kernel32.GlobalLock(data)
            try:
                return ctypes.cast(data_locked,ctypes.c_char_p).value
            finally:
                kernel32.GlobalUnlock(data_locked)
    finally:
        user32.CloseClipboard()

def set_clipboard_text(message):
    user32.OpenClipboard(user32.GetActiveWindow() or kernel32.GetConsoleWindow())
    message += b'\0'
    try:
        user32.EmptyClipboard()
        h = kernel32.GlobalAlloc(GMEM_MOVEABLE,len(message))
        data = kernel32.GlobalLock(h)
        try:
            kernel32.RtlCopyMemory(data,(ctypes.c_char * len(message))(*message),len(message))
        finally:
            kernel32.GlobalUnlock(data)
        user32.SetClipboardData(CF_TEXT,h)
        if user32.IsClipboardFormatAvailable(CF_TEXT):
            data = user32.GetClipboardData(CF_TEXT)
            data_locked = kernel32.GlobalLock(data)
            text = ctypes.c_char_p(data_locked)
            value = text.value
            kernel32.GlobalUnlock(data_locked)
            return value
    finally:
        user32.CloseClipboard()

print(get_clipboard_text())  # prints whatever was on the clipboard beforehand
msg = bytes(range(1,256))    # can't send byte 0 except as null terminator for CF_TEXT
set_clipboard_text(msg)
msg2 = get_clipboard_text()
assert msg == msg2

I'm on Mac and I was looking for a cross-platform way to achieve this.我在 Mac 上,我正在寻找一种跨平台的方式来实现这一点。 After a day of research, I was able to find this library called pyclip .经过一天的研究,我找到了这个名为pyclip的库。

$ python3 -m pip install pyclip # pyclip requires Python >=3.7

After installing pyclip , you can do stuff like this:安装pyclip后,您可以执行以下操作:

>>> import pyclip
>>> with open('test.jpg', 'rb') as f1:
...    data1 = f1.read()
...
>>> pyclip.copy(data1)
>>> data2 = pyclip.paste() # returns bytes, paste(text=True) for str
>>> with open('test2.jpg', 'wb') as f2:
...    f2.write(data2)
...
6194
>>> data1 == data2
True
>>>

Here's the PyPI page that includes the documentation.这是包含文档的PyPI 页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM