【问题标题】:Read text from clipboard in Windows using ctypes在 Windows 中使用 ctypes 从剪贴板读取文本
【发布时间】:2023-01-17 05:23:42
【问题描述】:

我试图通过在Python 3.6 中使用ctypes 来获取存储在剪贴板中的文本。我测试了很多在 Stack 和 GitHub 上找到的解决方案,但它们只适用于 Python 2Python 3.4

这是几乎随处可见的代码:

from ctypes import *

def get_clipboard_text():
    text = ""
    if windll.user32.OpenClipboard(c_int(0)):
        h_clip_mem = windll.user32.GetClipboardData(1)
        windll.kernel32.GlobalLock.restype = c_char_p
        text = windll.kernel32.GlobalLock(c_int(h_clip_mem))
        windll.kernel32.GlobalUnlock(c_int(h_clip_mem))
        windll.user32.CloseClipboard()
    return text

我在Python 3.4 测试过。它工作正常并返回剪贴板中的文本。但是在Python 3.6 上运行相同的脚本总是返回None。到目前为止,我找不到Python 3.6 的解决方案。

我想知道是否有人可以帮助我,因为我根本不了解ctypesC 编程。

【问题讨论】:

  • 你能包括你使用的进口吗?目前代码抛出很多NameErrors。
  • 对不起,导入已添加。

标签: python clipboard ctypes python-3.6


【解决方案1】:

我的猜测是您使用的是 64 位 Python 3.6,因此句柄是 64 位的,并且您将它们作为 c_int(32 位)传递。

对于 ctypes,最好明确所有参数和返回类型。以下代码应该适用于 32 位和 64 位 Python 2 和 3。

此外,CF_UNICODETEXT 将能够处理您复制的任何文本。

from __future__ import print_function
import ctypes
import ctypes.wintypes as w

CF_UNICODETEXT = 13

u32 = ctypes.WinDLL('user32')
k32 = ctypes.WinDLL('kernel32')

OpenClipboard = u32.OpenClipboard
OpenClipboard.argtypes = w.HWND,
OpenClipboard.restype = w.BOOL
GetClipboardData = u32.GetClipboardData
GetClipboardData.argtypes = w.UINT,
GetClipboardData.restype = w.HANDLE
GlobalLock = k32.GlobalLock
GlobalLock.argtypes = w.HGLOBAL,
GlobalLock.restype = w.LPVOID
GlobalUnlock = k32.GlobalUnlock
GlobalUnlock.argtypes = w.HGLOBAL,
GlobalUnlock.restype = w.BOOL
CloseClipboard = u32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = w.BOOL

def get_clipboard_text():
    text = ""
    if OpenClipboard(None):
        h_clip_mem = GetClipboardData(CF_UNICODETEXT)
        text = ctypes.wstring_at(GlobalLock(h_clip_mem))
        GlobalUnlock(h_clip_mem)
        CloseClipboard()
    return text

print(get_clipboard_text())

【讨论】:

  • 非常感谢,代码完美运行!没想到python有32位和64位版本。
  • @chrizator,内核和窗口句柄是 32 位的。但后者具有负值的特殊句柄必须符号扩展到 64 位。此外,一些句柄确实是内存地址,如HMODULEHGLOBAL,显然是GlobalLock的结果。在实践中,在使用句柄和指针时始终声明 argtypesrestype 以避免硬编码实现细节和假设。
  • 谢谢你的澄清。那么通过定义 argtypesrestypes 代码是否适用于 32 位和 64 位?很抱歉问了这些愚蠢的问题,但我对这个话题真的很陌生。
猜你喜欢
  • 1970-01-01
  • 2010-09-11
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
相关资源
最近更新 更多