在调用SetClipboardData后无法在文件资源管理器中粘贴文件

0 投票
1 回答
608 浏览
提问于 2025-04-18 07:10

我正在尝试用我的代码把一个图片文件复制到Windows的剪贴板,然后手动在Windows资源管理器中的任何文件夹里粘贴。我使用的是Windows 8 64位的笔记本电脑,运行Python 2.7pywin32-218来调用win32的API。

我成功地在Wordpad应用程序中粘贴了我的文件。但是,我无法在Windows资源管理器中粘贴,粘贴菜单是灰色的,无法使用。任何帮助或建议都非常感谢。

from win32api import *
from win32clipboard import *
import time
import pythoncom
import struct
from pywin32_testutil import str2bytes

import ctypes
msvcrt = ctypes.cdll.msvcrt
kernel32 = ctypes.windll.kernel32

ret_stg=None
GMEM_MOVEABLE = 0x0002

def set_clipboard(content):
    ret_stg = pythoncom.STGMEDIUM()
    fname_buf=str2bytes(content)

    fname_ba=bytearray(fname_buf)
    fname_ba.append('\0')
    fname_ba.append('\0')

    fmt="lllll%ss" %len(fname_ba)
    df=struct.pack(fmt, 20, 0, 0, 0, 0, str(fname_ba))
    ret_stg.set(pythoncom.TYMED_HGLOBAL, df)

    try:
        OpenClipboard()
    except:
        print "open failed, exception=%s"%FormatMessage(GetLastError())
    else: 
        try:
            SetClipboardData(CF_HDROP, ret_stg.data)
        except:
            print "set failed, exception = %s"%FormatMessage(GetLastError())
        finally:
            CloseClipboard()

def get_clipboard():
    try:
        OpenClipboard()
    except:
        print "open failed, exception=%s"%FormatMessage(GetLastError())
    else:   
        if(IsClipboardFormatAvailable(CF_HDROP)):
            handle = GetClipboardDataHandle(CF_HDROP)
            file_cnt = DragQueryFile(handle)
            print "file count = %ld"%file_cnt
            for i in range(0,file_cnt):
                file_path = DragQueryFile(handle, i)
                print "file name = %s"%file_path
        elif(IsClipboardFormatAvailable(CF_UNICODETEXT)):
            print "CF_UNICODETEXT content"
            clip_data = GetClipboardData(CF_UNICODETEXT)
            print "*** content = %s ***"%clip_data
        else:
            print "unsupported clipboard format"
    finally:
            CloseClipboard()

if __name__ == '__main__':
    file1 = "E:\\pics\\ferrari.jpg"
    set_clipboard(file1)
    time.sleep(1)
    get_clipboard()    

更新:出于某些奇怪的原因,上面的代码在Windows 7 64位中运行良好。我可以在Wordpad和资源管理器窗口中粘贴我的文件。

1 个回答

0

问题可能出在你传给剪贴板的内存需要通过GlobalAlloc来获取,之后还需要锁定、写入、解锁,然后才能传递。

可以看看这个链接里的代码:

http://www.c-plus-plus.de/forum/251309-full

我不太确定怎么把这个转换成Python,或者说这是否已经在内部完成了。

撰写回答