Проводник Windows и пользовательские типы файлов ярлыков
Windows имеет флаг при регистрации файлов, который называется "IsShortcut". Когда этот флаг установлен, файлу автоматически присваивается значок ярлыка, и он обрабатывается как ярлык другими способами (например, если щелкнуть правой кнопкой мыши и выбрать "Создать ярлык", он просто копирует файл вместо создания.lnk файл). Microsoft использует эту функцию для ссылок приложений ClickOnce (расширение .appref-ms
).
Мы используем эту функцию для настраиваемого типа файла ярлыка для нашего собственного программного обеспечения, и мы обнаружили, что начиная с Windows 10 (или, возможно, Windows 8) наши настраиваемые ярлыки не отображаются в меню "Пуск". Меню "Пуск" списков курсов .lnk
файлы, и это включает в себя .appref-ms
файлы, но наш собственный формат файла, регистрация которого существенно не отличается от .appref-ms
файлы, исключен из меню Пуск. Файлы ярлыков физически присутствуют в структуре папок меню "Пуск" (%APPDATA%\Microsoft\Windows\Start Menu\Programs
) но игнорируются проводником Windows. Другие типы ярлыков (.lnk
а также .appref-ms
) в том же каталоге действительно появляются.
То, что я ищу, - это некоторое указание на то, как Windows Explorer определяет, какие форматы файлов он будет включать в меню "Пуск", чтобы при разработке пользовательского формата его можно было указать таким же образом. Наш пользовательский формат отлично работал в Windows XP, Windows Vista и Windows 7, но более новый дизайн меню "Пуск" по некоторым причинам исключает наш формат файла, даже если он помечен IsShortcut
так же, как .appref-ms
файлы.
Возможно ли это сделать?:-)
1 ответ
Чтобы показать ссылку в стартовом меню Windows 10, IPropertyStore.GetValue
должен быть реализован и возвращать некоторую уникальную строку для PKEY_AppUserModel_ID
свойство.
Чтобы отобразить значок в стартовом меню Windows 10, IExtractIconW.GetIconLocation
должен быть реализован, и владельцем раздела реестра с классом CLSID (т.е. HKEY_CLASSES_ROOT\CLSID{42465C3A-83D3-4310-B27D-F271DE372764}) должен быть "NT Service\TrustedInstaller"
Вот пример реализации (расширенный код Джонатана Гилберта):https://github.com/publee/CustomShortcutFileType
(Это не ответ, но может помочь вам в ваших расследованиях.)
Я создал и зарегистрировал свое собственное расширение ссылки на оболочку. После перезапуска проводника он использует мое расширение и запрашивает различные свойства через интерфейс IPropertyStore. Полный журнал:
TMyLinkExtension.07BA12F0 is created
TMyLinkExtension.07BA12F0.QueryInterface IID_IShellLinkW out Result=S_OK
TMyLinkExtension.07BA12F0.QueryInterface IID_IInitializeWithFile out Result=S_OK
TMyLinkExtension.07BA12F0.IInitializeWithFile.Initialize started
TMyLinkExtension.07BA12F0.IInitializeWithFile.Initialize in AFileName=C:\Users\Dec\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Total Commander\1.mylnk
TMyLinkExtension.07BA12F0.IInitializeWithFile.Initialize in AOpenMode=STGM_READ
TMyLinkExtension.07BA12F0.IInitializeWithFile.Initialize out Result=S_OK
TMyLinkExtension.07BA12F0.IInitializeWithFile.Initialize finished
TMyLinkExtension.07BA12F0.QueryInterface IID_IShellLinkW out Result=S_OK
TMyLinkExtension.07BA12F0.QueryInterface IID_IShellLinkDataList out Result=S_OK
TMyLinkExtension.07BA12F0.IShellLinkDataList.GetFlags started
TMyLinkExtension.07BA12F0.IShellLinkDataList.GetFlags out Result=E_NOTIMPL
TMyLinkExtension.07BA12F0.IShellLinkDataList.GetFlags finished
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath started
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath in AFileName=0C1FF058
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath in AFileNameLength=260
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath in @AFindData=0C1FEE08
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath in AFlags=SLGP_RAWPATH
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath out Result=E_NOTIMPL
TMyLinkExtension.07BA12F0.IShellLinkW.GetPath finished
TMyLinkExtension.07BA12F0.QueryInterface IID_IPropertyStore out Result=S_OK
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey=PKEY_AppUserModel_ID (Caption: AppUserModelId, CanonicalName: System.AppUserModel.ID, Type: VT_LPWSTR)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey=PKEY_AppUserModel_PreventPinning (Caption: Prevent pinning, CanonicalName: System.AppUserModel.PreventPinning, Type: VT_BOOL)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out AData.vt=VT_BOOL
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out AData=0
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=S_OK
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey={9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 23 (Caption: System.AppUserModel.ExcludedFromLauncher, CanonicalName: System.AppUserModel.ExcludedFromLauncher, Type: VT_BOOL)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out AData.vt=VT_BOOL
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out AData=0
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=S_OK
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey={9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 14 (Caption: Host environment, CanonicalName: System.AppUserModel.HostEnvironment, Type: VT_UI4)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey=PKEY_AppUserModel_StartPinOption (Caption: Start pin option, CanonicalName: System.AppUserModel.StartPinOption, Type: VT_UI4)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey={9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 18 (Caption: Installed by, CanonicalName: System.AppUserModel.InstalledBy, Type: VT_UI4)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey=PKEY_AppUserModel_IsDualMode (Caption: Is dual mode, CanonicalName: System.AppUserModel.IsDualMode, Type: VT_BOOL)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue started
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue in AKey=PKEY_Link_Arguments (Caption: Arguments, CanonicalName: System.Link.Arguments, Type: VT_LPWSTR)
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue out Result=E_INVALIDARG
TMyLinkExtension.07BA12F0.IPropertyStore.GetValue finished
TMyLinkExtension.07BA12F0 is destroyed
Я пытался играть с разными значениями, но все еще не могу найти способ показать мой файл 1.mylnk в меню "Пуск", но, возможно, этот журнал поможет вам.