In python this can be done with pywin32 like so:
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)
But theoretically it can be done with only ctypes to avoid a dependency on 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()