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 = str(os.path.abspath(folderpath), 'mbcs')
iconpath = str(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)
How to change folder icons with Python on windows?