2011-01-11 14 views

Odpowiedz

7
import os 
import ctypes 
from ctypes import POINTER, Structure, c_wchar, c_int, sizeof, byref 
from ctypes.wintypes import BYTE, WORD, DWORD, LPWSTR, LPSTR 
import win32api  

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)]  

def seticon(folderpath, iconpath, iconindex): 
    """Set folder icon. 

    >>> seticon(".", "C:\\Windows\\system32\\SHELL32.dll", 10) 

    """ 
    shell32 = ctypes.windll.shell32 

    folderpath = unicode(os.path.abspath(folderpath), 'mbcs') 
    iconpath = unicode(os.path.abspath(iconpath), 'mbcs') 

    fcs = SHFOLDERCUSTOMSETTINGS() 
    fcs.dwSize = sizeof(fcs) 
    fcs.dwMask = FCSM_ICONFILE 
    fcs.pszIconFile = iconpath 
    fcs.cchIconFile = 0 
    fcs.iIconIndex = iconindex 

    hr = shell32.SHGetSetFolderCustomSettings(byref(fcs), folderpath, 
               FCS_FORCEWRITE) 
    if hr: 
     raise WindowsError(win32api.FormatMessage(hr)) 

    sfi = SHFILEINFO() 
    hr = shell32.SHGetFileInfoW(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) 
    if index == -1: 
     raise WindowsError() 

    shell32.SHUpdateImageW(sfi.szDisplayName, sfi.iIcon, 0, index) 
+0

Nie jestem pewien, jak sprawić, aby to działało ponownie, ale nie działa w Pythonie 3.x - "unicode" jest przestarzałe, a otrzymam komunikat OSError, jeśli skomentuję te dwie linie. –

1

z mojego zrozumienia, aby to zrobić trzeba Customise Folders with Desktop.ini. Chociaż może być więcej informacji na temat this question.

+0

Niesamowite, dokładnie tego chciałem. Wszystko, co muszę zrobić, to wygenerować ten plik, a Windows woli go odebrać. Dziękuję bardzo! –

+0

Niezupełnie. Atrybuty pliku muszą zawierać system i ukryty, a bez aktualizacji cache ikony Windows może nie wyświetlać poprawnej ikony. – cgohlke

+0

@Waldo, oczekując, że Windows będzie działać, jest niebezpiecznym nawykiem;) ale mam nadzieję, że i tak pomogłem. – William

Powiązane problemy