Python调用SHGetKnownFolderPath仅返回b'C',求排查错误原因
解决SHGetKnownFolderPath仅返回单个字符的问题
你的问题核心是字符串类型不匹配:Windows API的SHGetKnownFolderPath返回的是宽字符串指针(wchar_t*),但你用了单字节字符指针类型ctypes.c_char_p()来接收,导致读取错误。
宽字符串中每个字符占2字节,比如桌面路径C:\Users\XXX\Desktop的宽字符存储形式是C\x00:\x00U\x00s\x00e\x00r\x00s\x00\...,当用c_char_p读取时,会把第一个\x00(宽字符的第二个字节)当成字符串结束符,所以只得到了第一个字符b'C'。
修正后的代码
import contextlib import ctypes import ctypes.wintypes import os import pathlib import uuid try: wintypes_GUID = ctypes.wintypes.GUID except AttributeError: class wintypes_GUID(ctypes.Structure): _fields_ = [ ('Data1', ctypes.c_ulong), ('Data2', ctypes.c_ushort), ('Data3', ctypes.c_ushort), ('Data4', ctypes.c_ubyte * 8) ] @classmethod def _from_uuid(cls, u): u = uuid.UUID(u) u_str = f'{{{u!s}}}' result = wintypes_GUID() errno = ctypes.oledll.ole32.CLSIDFromString(u_str, ctypes.byref(result)) if errno == 0: return result else: raise RuntimeError(f'CLSIDFromString returned error code {errno}') DESKTOP_UUID = 'B4BFCC3A-DB2C-424C-B029-7FE99A87C641' def get_known_folder(uuid): # 改为用c_wchar_p接收宽字符串指针 result_ptr = ctypes.c_wchar_p() with _freeing(ctypes.oledll.ole32.CoTaskMemFree, result_ptr): errno = ctypes.windll.shell32.SHGetKnownFolderPath( ctypes.pointer(wintypes_GUID._from_uuid(uuid)), 0, None, ctypes.byref(result_ptr) ) if errno == 0: # c_wchar_p.value直接返回Python字符串,无需fsdecode result = result_ptr.value return pathlib.Path(result) else: raise RuntimeError(f'Shell32.SHGetKnownFolderPath returned error code {errno}') @contextlib.contextmanager def _freeing(freefunc, obj): try: yield obj finally: freefunc(obj) assert get_known_folder(DESKTOP_UUID) == pathlib.Path('~/Desktop').expanduser(), \ f'Result: {get_known_folder(DESKTOP_UUID)!r}; expected: {pathlib.Path("~/Desktop").expanduser()!r}'
关键修改点
- 替换指针类型:把
result_ptr = ctypes.c_char_p()改成ctypes.c_wchar_p(),对应Windows API的宽字符串返回类型。 - 简化字符串转换:
c_wchar_p.value直接返回Python原生字符串,不需要再用os.fsdecode()处理。 - 释放逻辑不变:不管是单字节还是宽字符串指针,
SHGetKnownFolderPath都是用CoTaskMemAlloc分配内存,所以CoTaskMemFree可以正常释放。
内容的提问来源于stack exchange,提问作者JamesTheAwesomeDude
相关产品推荐
相关产品推荐

