开发者

How to tell Windows Explorer to refresh its icons?

开发者 https://www.devze.com 2022-12-11 15:50 出处:网络
Once my installer finishes installing new versions of my application\'s exe, I\'d like to tell Explorer to use the new exe\'s icons for its shortcuts.However, I cannot figure out how to do this.

Once my installer finishes installing new versions of my application's exe, I'd like to tell Explorer to use the new exe's icons for its shortcuts. However, I cannot figure out how to do this.

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

It's entirely possible that I'm just doing something wrong. Any help would be appreciated.

Warning: Very ugly test code follows开发者_开发知识库.

#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


Your sledge-hammer approach is the one I've seen used to get this done. An oops in your code though, the "Shell Icon Size" value is a REG_SZ, not a REG_DWORD. Always VERIFY() the API function return values...

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号