我想为所有更改文件夹图标的操作系统(Win,MacOS,Unix,...)编写一般方法。
我想扩展以下实现
import os
import warnings
import ctypes
from ctypes import POINTER, Structure, c_wchar, c_int, sizeof, byref
from ctypes.wintypes import BYTE, WORD, DWORD, LPWSTR, LPSTR
import win32api
class SetFolderIcon(object):
def __init__(self, folderPath, iconPath, reset=False):
assert os.path.isdir(folderPath), "folderPath '%s' is not a valid folder"%folderPath
self.__folderPath = unicode(os.path.abspath(folderPath), 'mbcs')
assert os.path.isfile(iconPath), "iconPath '%s' does not exist"%iconPath
self.__iconPath = unicode(os.path.abspath(iconPath), 'mbcs')
assert isinstance(reset, bool), "reset must be boolean"
self.__reset = reset
# set icon if system is windows
if os.name == 'nt':
try:
self.__set_icon_on_windows()
except Exception as e:
warnings.warn("Unable to set folder icon (%s)"%e)
elif os.name == 'posix':
raise Exception('posix system not implemented yet')
elif os.name == 'mac':
raise Exception('mac system not implemented yet')
elif os.name == 'os2':
raise Exception('os2 system not implemented yet')
elif os.name == 'ce':
raise Exception('ce system not implemented yet')
elif os.name == 'java':
raise Exception('java system not implemented yet')
elif os.name == 'riscos':
raise Exception('riscos system not implemented yet')
def __set_icon_on_windows(self):
HICON = c_int
LPTSTR = LPWSTR
TCHAR = c_wchar
MAX_PATH = 260
FCSM_ICONFILE = 0x00000010
FCS_FORCEWRITE = 0x00000002
SHGFI_ICONLOCATION = 0x000001000
class GUID(Structure):
_fields_ = [ ('Data1', DWORD),
('Data2', WORD),
('Data3', WORD),
('Data4', BYTE * 8) ]
class SHFOLDERCUSTOMSETTINGS(Structure):
_fields_ = [ ('dwSize', DWORD),
('dwMask', DWORD),
('pvid', POINTER(GUID)),
('pszWebViewTemplate', LPTSTR),
('cchWebViewTemplate', DWORD),
('pszWebViewTemplateVersion', LPTSTR),
('pszInfoTip', LPTSTR),
('cchInfoTip', DWORD),
('pclsid', POINTER(GUID)),
('dwFlags', DWORD),
('pszIconFile', LPTSTR),
('cchIconFile', DWORD),
('iIconIndex', c_int),
('pszLogo', LPTSTR),
('cchLogo', DWORD) ]
class SHFILEINFO(Structure):
_fields_ = [ ('hIcon', HICON),
('iIcon', c_int),
('dwAttributes', DWORD),
('szDisplayName', TCHAR * MAX_PATH),
('szTypeName', TCHAR * 80) ]
shell32 = ctypes.windll.shell32
fcs = SHFOLDERCUSTOMSETTINGS()
fcs.dwSize = sizeof(fcs)
fcs.dwMask = FCSM_ICONFILE
fcs.pszIconFile = self.__iconPath
fcs.cchIconFile = 0
fcs.iIconIndex = self.__reset
hr = shell32.SHGetSetFolderCustomSettings(byref(fcs), self.__folderPath, FCS_FORCEWRITE)
if hr:
raise WindowsError(win32api.FormatMessage(hr))
sfi = SHFILEINFO()
hr = shell32.SHGetFileInfoW(self.__folderPath, 0, byref(sfi), sizeof(sfi), SHGFI_ICONLOCATION)
#if hr == 0:
# raise WindowsError(win32api.FormatMessage(hr))
index = shell32.Shell_GetCachedImageIndexW(sfi.szDisplayName, sfi.iIcon, 0)
shell32.SHUpdateImageW(sfi.szDisplayName, sfi.iIcon, 0, index)
iconPath = 'C:\\Users\\myself\\Desktop\\icon.ico'
#iconPath = "C:\\Windows\\system32\\SHELL32.dll"
SetFolderIcon('C:\\Users\\myself\\Desktop\\Newfolder',iconPath, reset=False)
# reset icon
SetFolderIcon('C:\\Users\\myself\\Desktop\\Newfolder',iconPath, reset=True)
如您所见,我只使用__set_icon_on_windows方法实现了Windows版本。类似的方法,如__set_icon_on_mac ...必须实现
由于