# A sample shell column provider # Mainly ported from MSDN article: # Using Shell Column Handlers for Detailed File Information, # Raymond Chen, Microsoft Corporation, February 2000 # # To demostrate: # * Execute this script to register the namespace. # * Open Windows Explorer # * Right-click an explorer column header - select "More" # * Locate column 'pyc size' or 'pyo size', and add it to the view. # This handler is providing that column data. import sys, os, stat import pythoncom from win32com.shell import shell, shellcon import commctrl import winerror from win32com.server.util import wrap from pywintypes import IID IPersist_Methods = ["GetClassID"] IColumnProvider_Methods = IPersist_Methods + \ ["Initialize", "GetColumnInfo", "GetItemData"] class ColumnProvider: _reg_progid_ = "Python.ShellExtension.ColumnProvider" _reg_desc_ = "Python Sample Shell Extension (Column Provider)" _reg_clsid_ = IID("{0F14101A-E05E-4070-BD54-83DFA58C3D68}") _com_interfaces_ = [pythoncom.IID_IPersist, shell.IID_IColumnProvider, ] _public_methods_ = IColumnProvider_Methods # IPersist def GetClassID(self): return self._reg_clsid_ # IColumnProvider def Initialize(self, colInit): flags, reserved, name = colInit print("ColumnProvider initializing for file", name) def GetColumnInfo(self, index): # We support exactly 2 columns - 'pyc size' and 'pyo size' if index in [0,1]: # As per the MSDN sample, use our CLSID as the fmtid if index==0: ext = ".pyc" else: ext = ".pyo" title = ext + " size" description = "Size of compiled %s file" % ext col_id = (self._reg_clsid_, # fmtid index) # pid col_info = ( col_id, # scid pythoncom.VT_I4, # vt commctrl.LVCFMT_RIGHT, # fmt 20, #cChars shellcon.SHCOLSTATE_TYPE_INT | \ shellcon.SHCOLSTATE_SECONDARYUI, # csFlags title, description) return col_info return None # Indicate no more columns. def GetItemData(self, colid, colData): fmt_id, pid = colid fmt_id==self._reg_clsid_ flags, attr, reserved, ext, name = colData if ext.lower() not in [".py", ".pyw"]: return None if pid==0: ext = ".pyc" else: ext = ".pyo" check_file = os.path.splitext(name)[0] + ext try: st = os.stat(check_file) return st[stat.ST_SIZE] except OSError: # No file return None def DllRegisterServer(): import winreg # Special ColumnProvider key key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, "Folder\\ShellEx\\ColumnHandlers\\" + \ str(ColumnProvider._reg_clsid_ )) winreg.SetValueEx(key, None, 0, winreg.REG_SZ, ColumnProvider._reg_desc_) print(ColumnProvider._reg_desc_, "registration complete.") def DllUnregisterServer(): import winreg try: key = winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, "Folder\\ShellEx\\ColumnHandlers\\" + \ str(ColumnProvider._reg_clsid_) ) except WindowsError as details: import errno if details.errno != errno.ENOENT: raise print(ColumnProvider._reg_desc_, "unregistration complete.") if __name__=='__main__': from win32com.server import register register.UseCommandLine(ColumnProvider, finalize_register = DllRegisterServer, finalize_unregister = DllUnregisterServer)