clipboard
2023-05-02 python Windows Clipboard pywin32 win32clipboard clipboard perl Win32::ClipboardI wanted to build simple script to get/set data in the clipboard in python. Something similar to what can be achieved with perl script and Win32::Clipboard module:
use Win32::Clipboard;
my $clip = Win32::Clipboard();
my $text = join ' ', @ARGV;
$clip->Set($text) if $text;
print $clip->Get();
This simply print out the contents of the clipboard to the console and if there are any parameters, it will put them into the clipboard.
In python, I found following ways to do such operation:
- with
ctypes
- with
pywin32
- with
clipboard
Lets look on each of them in more detail.
ctypes
The ctypes is a library that allows to interoperate with foreign DLLs. In our case, we use Windows libraries user32
and kernel32
to access the clipboard. I gathered the examples below from StackOverflow and other internet sources and I placed them here for the study purposes.
The ctypes
is included in python distribution and thus can be quite cheap solution that does not need to install any dependencies.
import sys
import ctypes
def get_clipboard():
CF_TEXT = 1
ctypes.windll.user32.OpenClipboard(0)
try:
if ctypes.windll.user32.IsClipboardFormatAvailable(CF_TEXT):
data = ctypes.windll.user32.GetClipboardData(CF_TEXT)
data_locked = ctypes.windll.kernel32.GlobalLock(data)
text = ctypes.c_char_p(data_locked)
value = text.value
ctypes.windll.kernel32.GlobalUnlock(data_locked)
return value
finally:
ctypes.windll.user32.CloseClipboard()
def set_clipboard(text):
CF_TEXT = 1
GMEM_DDESHARE = 0x2000
ctypes.windll.user32.OpenClipboard(0)
ctypes.windll.user32.EmptyClipboard()
try:
# works on Python 2 (bytes() only takes one argument)
hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text))+1)
except TypeError:
# works on Python 3 (bytes() requires an encoding)
hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text, 'ascii'))+1)
pchData = ctypes.windll.kernel32.GlobalLock(hCd)
try:
# works on Python 2 (bytes() only takes one argument)
ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pchData), bytes(text))
except TypeError:
# works on Python 3 (bytes() requires an encoding)
ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pchData), bytes(text, 'ascii'))
ctypes.windll.kernel32.GlobalUnlock(hCd)
ctypes.windll.user32.SetClipboardData(CF_TEXT, hCd)
ctypes.windll.user32.CloseClipboard()
text = ' '.join(sys.argv[1:])
if len(text) > 0:
set_clipboard(text)
print(get_clipboard())
You can see all the hoops that needs to be covered for calling quite simple functions. Just the memory allocation is rather wordy.
win32clipboard
The win32clipboard comes from pywin32 package (and can be installed with it). Usage is rather simple, you just need to keep in mind to open/close the clipboard to make it available to other applications.
import sys
import win32clipboard
def set_clipboard(text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
def get_clipboard():
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
return data
text = ' '.join(sys.argv[1:])
if len(text) > 0:
set_clipboard(text)
print(get_clipboard())
clipboard
Probably simplest interface for text data. It also should be multi-platform solution as it is based on pyperclip that works on all Windows, Linux, and Mac.
import sys
import clipboard
text = ' '.join(sys.argv[1:])
if len(text) > 0:
clipboard.copy(text)
print(clipboard.paste())