2011-01-11 26 views

Respuesta

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

No estoy seguro de cómo hacer que funcione de nuevo, pero no funciona en Python 3.x - "Unicode" está en desuso, y obtengo un error de OS si hago un comentario sobre esas dos líneas. –

1

Desde mi entendimiento para hacer esto se debe Customise Folders with Desktop.ini. Aunque podría haber más información en this question.

+0

Impresionante, eso es exactamente lo que quería. Todo lo que tengo que hacer es generar ese archivo, y las ventanas lo recogerán, supongo. ¡Muchas gracias! –

+0

No del todo. Los atributos del archivo deben incluir System y Hidden, y sin actualizar el caché del icono, es posible que Windows no muestre el ícono correcto. – cgohlke

+0

@Waldo, esperando que Windows haga cosas es un hábito peligroso;) pero espero haber ayudado de todos modos. – William

Cuestiones relacionadas