使用 ctypes 通过 SHOpenFolderAndSelectItems 打开资源管理器并选择文件
在 python 中,这可以使用 pywin32 来完成,如下所示:
from win32com.shell import shell
def showFilesInExplorer(folder, files):
folder_pidl = shell.SHILCreateFromPath(folder, 0)[0]
files_pidl = [shell.SHILCreateFromPath(f, 0)[0] for f in files]
shell.SHOpenFolderAndSelectItems(folder_pidl, files_pidl, 0)
但理论上它可以仅使用 ctypes 来完成,以避免对 pywin32 的依赖。
import ctypes
ctypes.windll.ole32.CoInitialize.restype = ctypes.HRESULT
ctypes.windll.ole32.CoInitialize.argtypes = [ctypes.c_void_p]
ctypes.windll.ole32.CoUninitialize.restype = None
ctypes.windll.ole32.CoUninitialize.argtypes = None
ctypes.windll.shell32.ILCreateFromPathW.restype = ctypes.c_void_p
ctypes.windll.shell32.ILCreateFromPathW.argtypes = [ctypes.c_char_p]
ctypes.windll.shell32.SHOpenFolderAndSelectItems.restype = ctypes.HRESULT
ctypes.windll.shell32.SHOpenFolderAndSelectItems.argtypes = [ctypes.c_void_p, ctypes.c_uint, ctypes.c_void_p, ctypes.c_ulong]
ctypes.windll.shell32.ILFree.restype = None
ctypes.windll.shell32.ILFree.argtypes = [ctypes.c_void_p]
def showFilesInExplorer(folder, files):
ctypes.windll.ole32.CoInitialize(None)
folder_pidl = ctypes.windll.shell32.ILCreateFromPathW(folder.encode('utf-16le') + b'\0')
files_pidl = [ctypes.windll.shell32.ILCreateFromPathW(f.encode('utf-16le') + b'\0') for f in files]
files_pidl_arr = (ctypes.c_void_p * len(files_pidl))(*files_pidl)
ctypes.windll.shell32.SHOpenFolderAndSelectItems(folder_pidl, len(files_pidl_arr), files_pidl_arr, 0)
for pidl in files_pidl[::-1]:
ctypes.windll.shell32.ILFree(pidl)
ctypes.windll.shell32.ILFree(folder_pidl)
ctypes.windll.ole32.CoUninitialize()