Как сообщить обозревателю Windows обновить свои значки?

73
8

Как только мой установщик завершит установку новых версий моего приложения exe, я хотел бы сказать, что Explorer использует новые значки exe для своих ярлыков. Однако я не могу понять, как это сделать.


Из чтения онлайн, похоже, проблема заключается в том, что системный список изображений кэширует старую версию значка. Я попытался вызвать SHChangeNotify с параметром SHCNE_UPDATEIMAGE. Я попытался позвонить SHUpdateImage. Я даже пробовал кувалдой для трансляции WM_SETTINGCHANGE. Кажется, что ничего не работает.


Совершенно возможно, что я просто делаю что-то неправильно. Любая помощь будет оценена.


Предупреждение: появляется очень уродливый тестовый код.


#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

спросил(а) 2009-11-18T20:35:00+03:00 10 лет, 4 месяца назад
1
Решение
61

Ваш подход с санным молотом - это тот, который я видел, чтобы это сделать. Тем не менее, в вашем коде есть значение "Размер значка" Shell "- REG_SZ, а не REG_DWORD. Всегда VERIFY() возвращаемые значения функции API...

ответил(а) 2009-11-18T22:05:00+03:00 10 лет, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема