Is there a way to only update one folder's desktop.ini?

223 views Asked by At

I am making a project involving the icons of the folders on my windows desktop. When I change the icon with python, the change doesn't occur immediately. You have to refresh it somehow (for example restart your laptop). And to counter this I searched the internet and found this piece of code from this github page: https://github.com/sunshowers/iconrefresher/blob/master/refresh-icons.py

def update_folder_icon():
    # !/usr/bin/env python

    # Released to the public domain.
    # http://creativecommons.org/publicdomain/zero/1.0/

    import ctypes
    from ctypes import wintypes

    # http://msdn.microsoft.com/en-us/library/ms644950
    SendMessageTimeout = ctypes.windll.user32.SendMessageTimeoutA
    SendMessageTimeout.restype = wintypes.LPARAM  # aka LRESULT
    SendMessageTimeout.argtypes = [wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM,
                                   wintypes.UINT, wintypes.UINT, ctypes.c_void_p]

    # http://msdn.microsoft.com/en-us/library/bb762118
    SHChangeNotify = ctypes.windll.shell32.SHChangeNotify
    SHChangeNotify.restype = None
    SHChangeNotify.argtypes = [wintypes.LONG, wintypes.UINT, wintypes.LPCVOID, wintypes.LPCVOID]

    HWND_BROADCAST = 0xFFFF
    WM_SETTINGCHANGE = 0x001A
    SMTO_ABORTIFHUNG = 0x0002
    SHCNE_ASSOCCHANGED = 0x08000000

    SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0, SMTO_ABORTIFHUNG, 5000, None)
    SHChangeNotify(SHCNE_ASSOCCHANGED, 0, None, None)

Everytime I use this code all of the folder icons refresh and blink. I need to use this code very often in my project (as often as every 3 seconds) so it would be nice to not see the blinking effect every single time. So my question is: Is there a way for me to only update one specific folder by for example passing the folder path as a parameter to the update_folder_icon() function?


Here is the code I use to change the icons of folder:

def set_folder_icon(folder_path, icon_path):
    if not os.path.isdir(folder_path):
        print("Folder Required To Set The Icon!")
        return

    shell32 = ctypes.windll.shell32

    folder_path = os.path.abspath(folder_path)
    icon_path = os.path.abspath(icon_path)

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

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

    sfi = SHFILEINFO()
    hr = shell32.SHGetFileInfoW(folder_path, 0, byref(sfi), sizeof(sfi),
                                SHGFI_ICONLOCATION)

    if hr == 0:
        raise WindowsError(win32api.FormatMessage(hr))

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

Other possibly useful information:

  • Windows Version: Windows 11
  • Python version: 3.8
  • IDE: Pycharm
1

There are 1 answers

0
Progrix On BEST ANSWER

I managed to solve the issue. The issue wasn't really the code itself, it was more like a windows bug. When you set the icon of a folder the first time it works, but when you change the icon again, but the icon file has the same name then the change doesn't happen. So to counter this you either have to do something aggressive like SHCNE_ASSOCCHANGED or simply use a different icon file name.