def show_files_win32(path, files): """Takes a path to a directory and a list of filenames in that directory to display. Returns True on success. """ assert os.name == "nt" import pywintypes from win32com.shell import shell assert is_fsnative(path) assert all(is_fsnative(f) for f in files) normalized_files = map(normalize_path, files) try: folder_pidl = shell.SHILCreateFromPath(path, 0)[0] desktop = shell.SHGetDesktopFolder() shell_folder = desktop.BindToObject( folder_pidl, None, shell.IID_IShellFolder) items = [] for item in shell_folder: name = desktop.GetDisplayNameOf(item, 0) if normalize_path(name) in normalized_files: items.append(item) shell.SHOpenFolderAndSelectItems(folder_pidl, items, 0) except pywintypes.com_error: return False else: return True
def shell_notify(paths, noassoc=False): try: from win32com.shell import shell, shellcon import pywintypes except ImportError: return dirs = set() for path in paths: if path is None: continue abspath = os.path.abspath(path) if not os.path.isdir(abspath): abspath = os.path.dirname(abspath) dirs.add(abspath) # send notifications to deepest directories first for dir in sorted(dirs, key=len, reverse=True): try: pidl, ignore = shell.SHILCreateFromPath(dir, 0) except pywintypes.com_error: return if pidl is None: continue shell.SHChangeNotify(shellcon.SHCNE_UPDATEITEM, shellcon.SHCNF_IDLIST | shellcon.SHCNF_FLUSH, pidl, None) if not noassoc: shell.SHChangeNotify(shellcon.SHCNE_ASSOCCHANGED, shellcon.SHCNF_FLUSH, None, None)
def launch_file_explorer(path, files=None): ''' Given a absolute base path and names of its children (no path), open up one File Explorer window with all the child files selected Taken from http://mail.python.org/pipermail/python-win32/2012-September/012533.html ''' if not files: path, files = os.path.split(path) files = [files] else: files = [os.path.basename(f) for f in files] if sys.getwindowsversion().major == 5: #if windows xp folder_pidl = shell.SHILCreateFromPath(path, 0)[0] desktop = shell.SHGetDesktopFolder() shell_folder = desktop.BindToObject(folder_pidl, None, shell.IID_IShellFolder) name_to_item_mapping = dict([(desktop.GetDisplayNameOf(item, 0), item) for item in shell_folder]) to_show = [] for f in files: if name_to_item_mapping.has_key(f): to_show.append(name_to_item_mapping[f]) # else: # raise Exception('f: "%s" not found in "%s"' % (f, path)) shell.SHOpenFolderAndSelectItems(folder_pidl, to_show, 0) else: # no SHILCreateFromPath in windows 7 f = os.path.join(path, files[0]) f_mbcs = f.encode('mbcs') if os.path.exists(f_mbcs): os.system(r'explorer /select,"%s"' % f_mbcs) else: os.startfile(path)
def update_colinfo(not_used, dir_name, fnames): for fname in fnames: full_fname = os.path.join(dir_name, fname) if os.path.isdir(full_fname): print(full_fname) pidl = shell.SHILCreateFromPath(full_fname, 0)[0] pb = shell.SHGetViewStatePropertyBag( pidl, "Shell", shellcon.SHGVSPB_FOLDERNODEFAULTS, pythoncom.IID_IPropertyBag, ) ## not all folders already have column info, and we're replacing it anyway pb.Write("ColInfo", template_stream) iunk = pb.Read("ColInfo", pythoncom.VT_UNKNOWN) s = iunk.QueryInterface(pythoncom.IID_IStream) s.Write(template_colinfo) s = None ## attribute names read from registry, can't find any way to enumerate IPropertyBag for attr in ( "Address", "Buttons", "Col", "Vid", "WFlags", "FFlags", "Sort", "SortDir", "ShowCmd", "FolderType", "Mode", "Rev", ): pb.Write(attr, template_pb.Read(attr)) pb = None
def selectdir_win(initialdir): title = 'Select directory' pidl = shell.SHILCreateFromPath(initialdir, 0)[0] pidl, display_name, image_list = shell.SHBrowseForFolder(None, pidl, title, 0, None, None) if (pidl, display_name, image_list) == (None, None, None): return None else: path = shell.SHGetPathFromIDList(pidl) return path
def property_sets(filepath): pidl, flags = shell.SHILCreateFromPath(os.path.abspath(filepath), 0) property_set_storage = shell.SHGetDesktopFolder().BindToStorage(pidl, None, pythoncom.IID_IPropertySetStorage) for fmtid, clsid, flags, ctime, mtime, atime in property_set_storage: yield FORMATS.get(fmtid, unicode(fmtid)), property_dict(property_set_storage, fmtid) if fmtid == pythoncom.FMTID_DocSummaryInformation: fmtid = pythoncom.FMTID_UserDefinedProperties user_defined_properties = property_dict(property_set_storage, fmtid) if user_defined_properties: yield FORMATS.get(fmtid, unicode(fmtid)), user_defined_properties
def selectfiles(show): folders = defaultdict(list) for p in show: folders[os.path.dirname(p)].append(os.path.basename(p)) for path, files in folders.iteritems(): files = set(os.path.splitext(f)[0] for f in files) | set(files) folder = shell.SHILCreateFromPath(path, 0)[0] desktop = shell.SHGetDesktopFolder() shell_folder = desktop.BindToObject(folder, None, shell.IID_IShellFolder) shell.SHOpenFolderAndSelectItems( folder, [item for item in shell_folder if desktop.GetDisplayNameOf(item, 0) in files], 0) return 0
def shell_entry(shell_entry=core.UNSET): if shell_entry is None: return None elif shell_entry is core.UNSET: return ShellFolder([], desktop) elif isinstance(ShellEntry, shell_entry): return shell_entry elif isinstance(shell_entry, basestring): pidl, flags = shell.SHILCreateFromPath(os.path.abspath(shell_folder), SHCONTF.FOLDERS) if pidl is None: return ShellFolder( shell.SHGetFolderLocation(None, CSIDL.constant(shell_entry), None, 0), desktop) pidl = None return ShellFolder( desktop.BindToObject(pidl, None, shell.IID_IShellFolder))
def shell_notify(paths): ''' Refresh Windows shell when file states change. This allows the explorer to refresh their icons based on their new state ''' if not os.name == 'nt': return try: from win32com.shell import shell, shellcon for path in paths: abspath = os.path.abspath(path) pidl, ignore = shell.SHILCreateFromPath(abspath, 0) shell.SHChangeNotify(shellcon.SHCNE_UPDATEITEM, shellcon.SHCNF_IDLIST | shellcon.SHCNF_FLUSHNOWAIT, pidl, None) except ImportError: pass
def launch_file_explorer(pathes): '''Given a list of Path up one File Explorer window per folder with all the child files selected''' folders = defaultdict(list) for p in pathes: folders[str(p.parent)].append(p.name) for path, files in folders.items(): folder_pidl = shell.SHILCreateFromPath(path, 0)[0] desktop = shell.SHGetDesktopFolder() shell_folder = desktop.BindToObject(folder_pidl, None, shell.IID_IShellFolder) name_to_item_mapping = dict([(desktop.GetDisplayNameOf(item, 0), item) for item in shell_folder]) to_show = [] for file in files: if not file in name_to_item_mapping: wx.LogMessage('File: "%s" not found in "%s"' % (file, path)) continue to_show.append(name_to_item_mapping[file]) shell.SHOpenFolderAndSelectItems(folder_pidl, to_show, 0)
def shell_folder(shell_folder=core.UNSET, parent=core.UNSET): if shell_folder is None: return None elif shell_folder is core.UNSET: return ShellFolder([], desktop) elif isinstance(shell_folder, PyIShellFolder): return ShellFolder(shell_folder) elif isinstance(shell_folder, basestring): pidl, flags = shell.SHILCreateFromPath(os.path.abspath(shell_folder), 0) if pidl is None: pidl = shell.SHGetFolderLocation(None, CSIDL.constant(shell_folder), None, 0) return ShellFolder( desktop.BindToObject(pidl, None, shell.IID_IShellFolder)) elif isinstance(shell_folder, list): if parent is core.UNSET: raise x_shell(errctx="shell_folder", errmsg="Cannot bind to PIDL without parent") return ShellFolder( parent.BindToObject(shell_folder, None, shell.IID_IShellFolder)) else: raise x_shell(errctx="shell_folder")
""" Demonstrates how to propagate a folder's view state to all its subfolders The format of the ColInfo stream is apparently undocumented, but it can be read raw from one folder and copied to another's view state. """ from win32com.shell import shell, shellcon import pythoncom import os, sys template_folder = os.path.split(sys.executable)[0] print 'Template folder:', template_folder template_pidl = shell.SHILCreateFromPath(template_folder, 0)[0] template_pb = shell.SHGetViewStatePropertyBag( template_pidl, "Shell", shellcon.SHGVSPB_FOLDERNODEFAULTS, pythoncom.IID_IPropertyBag) # Column info has to be read as a stream # This may blow up if folder has never been opened in Explorer and has no ColInfo yet template_iunk = template_pb.Read('ColInfo', pythoncom.VT_UNKNOWN) template_stream = template_iunk.QueryInterface(pythoncom.IID_IStream) streamsize = template_stream.Stat()[2] template_colinfo = template_stream.Read(streamsize) def update_colinfo(not_used, dir_name, fnames): for fname in fnames: full_fname = os.path.join(dir_name, fname) if os.path.isdir(full_fname): print full_fname pidl = shell.SHILCreateFromPath(full_fname, 0)[0]
def updateDir(path): pidl, _ = shell.SHILCreateFromPath(path, 0) shell.SHChangeNotify(shellcon.SHCNE_UPDATEDIR, shellcon.SHCNF_IDLIST | shellcon.SHCNF_FLUSH, pidl, None)
def __init__(self, filepath): self._pidl, _ = shell.SHILCreateFromPath(os.path.abspath(filepath), 0) self._pss = _desktop.BindToStorage(self._pidl, None, pythoncom.IID_IPropertySetStorage)
## https://mail.python.org/pipermail/python-list/2009-June/539760.html import os, sys from win32com.shell import shell, shellcon import pythoncom from win32com import storagecon filepath = sys.argv[1] pidl, flags = shell.SHILCreateFromPath (os.path.abspath (filepath), 0) property_set_storage = shell.SHGetDesktopFolder().BindToStorage ( pidl, None, pythoncom.IID_IPropertySetStorage ) summary_info = property_set_storage.Open ( pythoncom.FMTID_SummaryInformation, storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE ) summary_info.WriteMultiple ([storagecon.PIDSI_TITLE], ["BLAHBLAH2"])