How do I tell Windows to update my icons?

As soon as my installer completes the installation of new versions of my exe application, I would like to say that Explorer uses the new exe icons for its shortcuts. However, I cannot figure out how to do this.

From reading online, it seems like the problem is that the system image list is caching the old version of the icon. I tried calling SHChangeNotify with the SHCNE_UPDATEIMAGE parameter. I tried calling SHUpdateImage . I even tried the sledgehammer to broadcast WM_SETTINGCHANGE . Nothing seems to work.

It is entirely possible that I am just doing something wrong. Any help would be appreciated.

Warning: a very ugly test code appears.

 #if 1 // First attempt: using shell functions wchar_t icon_path[MAX_PATH]; int icon_index; UINT icon_flags; IShellFolder *desktop_folder; IShellFolder *sub_folder; IExtractIcon *extract_icon; LPITEMIDLIST pidl; SHGetDesktopFolder(&desktop_folder); wchar_t *folder_path = L"C:\\Documents and Settings\\All Users\\Start Menu\\Programs\\MyCompany\\"; desktop_folder->ParseDisplayName(NULL, NULL, folder_path, NULL, &pidl, NULL); desktop_folder->BindToObject(pidl, NULL, IID_IShellFolder, (void**) &sub_folder); sub_folder->ParseDisplayName(NULL, NULL, L"MyApp.lnk", NULL, &pidl, NULL); sub_folder->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*) &pidl, IID_IExtractIcon, NULL, (void**) &extract_icon); extract_icon->GetIconLocation(0, icon_path, MAX_PATH, &icon_index, &icon_flags); SHFILEINFO sfi; DWORD_PTR result = SHGetFileInfo(shortcut_path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_LARGEICON); SHUpdateImage(icon_path, icon_index, icon_flags, sfi.iIcon); // sfi.iIcon should be correct, but we'll try both, just for fun... SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD, NULL, (LPCVOID) icon_index); SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD, NULL, (LPCVOID) sfi.iIcon); #else // Second attempt: broadcasting a settings change HKEY reg; RegCreateKeyEx(HKEY_CURRENT_USER, L"Control Panel\\Desktop\\WindowMetrics", 0, NULL, 0, KEY_SET_VALUE, NULL, &reg, NULL); DWORD value; value = 33; RegSetValueEx(reg, L"Shell Icon Size", 0, REG_DWORD, (BYTE*) &value, sizeof(value)); value = 32; SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, (int) L"WindowMetrics"); RegSetValueEx(reg, L"Shell Icon Size", 0, REG_DWORD, (BYTE*) &value, sizeof(value)); SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, (int) L"WindowMetrics"); #endif 
+3
source share
1 answer

Your sledgehammer approach is the one I saw to do this. However, your code has a β€œShell icon size value of REG_SZ , not REG_DWORD . Always VERIFY () the return values ​​of the API function ...

+2
source

Source: https://habr.com/ru/post/1435522/


All Articles