Kano001's picture
Upload 261 files
10865e1 verified
raw
history blame
2.55 kB
# A sample icon handler. Sets the icon for Python files to a random
# ICO file. ICO files are found in the Python directory - generally there will
# be 3 icons found.
#
# To demostrate:
# * Execute this script to register the context menu.
# * Open Windows Explorer, and browse to a directory with a .py file.
# * Note the pretty, random selection of icons!
# Use glob to locate ico files, and random.choice to pick one.
import glob
import os
import random
import sys
import pythoncom
import win32gui
import winerror
from win32com.shell import shell, shellcon
ico_files = glob.glob(os.path.join(sys.prefix, "*.ico"))
if not ico_files:
ico_files = glob.glob(os.path.join(sys.prefix, "PC", "*.ico"))
if not ico_files:
print("WARNING: Can't find any icon files")
# Our shell extension.
IExtractIcon_Methods = "Extract GetIconLocation".split()
IPersistFile_Methods = "IsDirty Load Save SaveCompleted GetCurFile".split()
class ShellExtension:
_reg_progid_ = "Python.ShellExtension.IconHandler"
_reg_desc_ = "Python Sample Shell Extension (icon handler)"
_reg_clsid_ = "{a97e32d7-3b78-448c-b341-418120ea9227}"
_com_interfaces_ = [shell.IID_IExtractIcon, pythoncom.IID_IPersistFile]
_public_methods_ = IExtractIcon_Methods + IPersistFile_Methods
def Load(self, filename, mode):
self.filename = filename
self.mode = mode
def GetIconLocation(self, flags):
# note - returning a single int will set the HRESULT (eg, S_FALSE,
# E_PENDING - see MS docs for details.
return random.choice(ico_files), 0, 0
def Extract(self, fname, index, size):
return winerror.S_FALSE
def DllRegisterServer():
import winreg
key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, "Python.File\\shellex")
subkey = winreg.CreateKey(key, "IconHandler")
winreg.SetValueEx(subkey, None, 0, winreg.REG_SZ, ShellExtension._reg_clsid_)
print(ShellExtension._reg_desc_, "registration complete.")
def DllUnregisterServer():
import winreg
try:
key = winreg.DeleteKey(
winreg.HKEY_CLASSES_ROOT, "Python.File\\shellex\\IconHandler"
)
except WindowsError as details:
import errno
if details.errno != errno.ENOENT:
raise
print(ShellExtension._reg_desc_, "unregistration complete.")
if __name__ == "__main__":
from win32com.server import register
register.UseCommandLine(
ShellExtension,
finalize_register=DllRegisterServer,
finalize_unregister=DllUnregisterServer,
)