Blog. Just Blog

Как закрепить программу в панели задач на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Как закрепить программу в панели задач на Ассемблере
Как закрепить программу в панели задач на Ассемблере

В Windows 7 есть возможность закрепления часто используемых программ прямо на панели задач. Что-то типа панели быстрого запуска предыдущих версий Windows, только более ущербное. Некоторые инсталляторы автоматически закрепляют устанавливаемые ими программы на панели задач без подтверждения пользователя, и мне стало интересно, как это можно сделать программным путем. В качестве языка для реализации, естественно, был выбран Ассемблер, но тут используются стандартные WinAPI, так что можно без проблем переписать на любой другой язык программирования.

Кратко, для закрепления программы на панели задач используется функция ShellExecute с параметром taskbarpin и она же, но с параметром taskbarunpin для изъятия программы из панели задач. Сперва опишем все необходимые значения в сегменте данных:
  1. section '.data' data readable writeable
  2.  
  3. ; Команды для ShellExecute
  4. szPin    db 'taskbarpin',0
  5. szUnpin  db 'taskbarunpin',0
  6.  
  7. ; Путь к ярлыку, который надо закрепить или удалить
  8. szLink   db 'c:\Program Files\Microsoft Games\Solitaire\SolitaireMCE.lnk',0
Чуть ниже я подробно остановлюсь на особенностях выполнения этих команд. А пока начнем с примера, как закрепить программу на панели задач. Делается это в одну строчку:
  1.         ; Закрепить программу на панели задач
  2.         invoke  ShellExecute,NULL,szPin,szLink,NULL,NULL,0
  3.         cmp     eax,20h
  4.         ja      pinned_ok
  5.  
  6. pinned_error:
  7.         ; Ошибка закрепления программы на панели задач
  8.         ...
  9.  
  10. pinned_ok:
  11.         ; Программа успешно закреплена на панели задач
  12.         ...
В качестве единственного параметра команда taskbarpin принимает ссылку на .lnk-файл, который, в свою очередь, должен ссылаться на нужный исполняемый файл. Никакой другой вид файлов закрепить на панели задач не получится. Но и тут есть свои особенности: закрепить можно не любой ярлык, а только тот, целевой объект которого находится на несъемном диске. При попытке закрепить ярлык, ссылающийся на файл, например, на флешке, функция вернет ошибку. Путь к файлу ярлыка должен быть полным, переменные окружения недопустимы. Результат выполнения должен превышать 20h, это будет означать, что функция отработала успешно. Любое значение меньше или равное 20h считается ошибкой.

Чтобы изъять программу из панели задач, надо точно также задействовать функцию ShellExecute, но только команда будет taskbarunpin. Остальные параметры и особенности такие же, как и при закреплении ярлыка.
  1.         ; Изъять программу из панели задач
  2.         invoke  ShellExecute,NULL,szUnpin,szLink,NULL,NULL,0
  3.         cmp     eax,20h
  4.         ja      unpinned_ok
  5.  
  6. unpinned_error:
  7.         ; Ошибка изъятия программы из панели задач
  8.         ...
  9.  
  10. unpinned_ok:
  11.         ; Программа успешно изъята из панели задач
  12.         ...
Есть еще один способ добавить или убрать ярлык на панели задач, он считается более правильным. Но сперва надо описать все необходимые константы, GUID'ы и интерфейсы. Их получается много, так как для каждой версии Windows используется свой интерфейс, а методы у них различаются.
  1. CLSCTX_INPROC_SERVER    = 1
  2. S_OK                    = 0
  3. PLMC_EXPLORER           = 4
  4.  
  5. ; Windows Vista
  6. ; GUID {C3C6EB6D-C837-4EAE-B172-5FEC52A2A4FD}
  7. IID_IPinnedList dd 0C3C6EB6Dh
  8.                 dw 0C837h
  9.                 dw 04EAEh
  10.                 db 0B1h, 072h, 05Fh, 0ECh, 052h, 0A2h, 0A4h, 0FDh
  11.  
  12. ; Windows 7, 8, 8.1
  13. ; GUID {BBD20037-BC0E-42F1-913F-E2936BB0EA0C}
  14. IID_IPinnedList2 dd 0BBD20037h
  15.                  dw 0BC0Eh
  16.                  dw 042F1h
  17.                  db 091h, 03Fh, 0E2h, 093h, 06Bh, 0B0h, 0EAh, 00Ch
  18.  
  19. ; Windows 10
  20. ; GUID {0DD79AE2-D156-45D4-9EEB-3B549769E940}
  21. IID_IPinnedList3 dd 00DD79AE2h
  22.                  dw 0D156h
  23.                  dw 045D4h
  24.                  db 09Eh, 0EBh, 03Bh, 054h, 097h, 069h, 0E9h, 040h
  25.  
  26. ; IID_IPinnedList Interface
  27. struct IPinnedList
  28.     ; IUnknown
  29.     QueryInterface dd ?
  30.     AddRef         dd ?
  31.     Release        dd ?
  32.     ; IPinnedList
  33.     EnumObjects    dd ?
  34.     Modify         dd ?
  35.     GetChangeCount dd ?
  36.     IsPinnable     dd ?
  37.     Resolve        dd ?
  38.     IsPinned       dd ?
  39. ends
  40.  
  41. ; IID_IPinnedList2 Interface
  42. struct IPinnedList2
  43.     ; IUnknown
  44.     QueryInterface                   dd ?
  45.     AddRef                           dd ?
  46.     Release                          dd ?
  47.     ; IPinnedList2
  48.     EnumObjects                      dd ?
  49.     Modify                           dd ?
  50.     GetChangeCount                   dd ?
  51.     GetPinnableInfo                  dd ?
  52.     IsPinnable                       dd ?
  53.     Resolve                          dd ?
  54.     IsPinned                         dd ?
  55.     GetPinnedItem                    dd ?
  56.     GetAppIDForPinnedItem            dd ?
  57.     ItemChangeNotify                 dd ?
  58.     UpdateForRemovedItemsAsNecessary dd ?
  59. ends
  60.  
  61. ; IID_IPinnedList3 Interface
  62. struct IPinnedList3
  63.     ; IUnknown
  64.     QueryInterface                   dd ?
  65.     AddRef                           dd ?
  66.     Release                          dd ?
  67.     ; IPinnedList3
  68.     EnumObjects                      dd ?
  69.     GetPinnableInfo                  dd ?
  70.     IsPinnable                       dd ?
  71.     Resolve                          dd ?
  72.     LegacyModify                     dd ?
  73.     GetChangeCount                   dd ?
  74.     IsPinned                         dd ?
  75.     GetPinnedItem                    dd ?
  76.     GetAppIDForPinnedItem            dd ?
  77.     ItemChangeNotify                 dd ?
  78.     UpdateForRemovedItemsAsNecessary dd ?
  79.     PinShellLink                     dd ?
  80.     GetPinnedItemForAppID            dd ?
  81.     Modify                           dd ?
  82. ends
  83.  
  84. ; GUID {90AA3A4E-1CBA-4233-B8BB-535773D48449}
  85. CLSID_TaskbarPin dd 090AA3A4Eh
  86.                  dw 01CBAh
  87.                  dw 04233h
  88.                  db 0B8h, 0BBh, 053h, 057h, 073h, 0D4h, 084h, 049h
Для Windows Vista используется интерфейс IPinnedList, для Windows 7 и 8 - интерфейс IPinnedList2, а для Windows 10 сборки 1809 и выше - интерфейс IPinnedList3. Для более младших сборок Windows 10 придется использовать описанный выше способ. С помощью метода IsPinned можно узнать, уже закреплена нужная программа на панели задач или нет. Методы Modify интерфейсов IPinnedList и IPinnedList2 совпадают по параметрам, а в интерфейсе IPinnedList3 добавляется еще один параметр. Остальное смотрите по коду, все прокомментировано и должно быть понятным, тут выполняются обычные действия с COM-объектами. Что интересно, все интерфейсы IPinnedList до сих пор относятся к недокументированным.
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.  
  4.         ; Попробовать создать объект (Win10 build 1809+)
  5.         invoke  CoCreateInstance,CLSID_TaskbarPin,NULL,\
  6.                 CLSCTX_INPROC_SERVER,\
  7.                 IID_IPinnedList3,ppv3
  8.         cmp     eax,S_OK
  9.         jz      @f
  10.  
  11.         ; Попробовать создать объект (Win7-8)
  12.         invoke  CoCreateInstance,CLSID_TaskbarPin,NULL,\
  13.                 CLSCTX_INPROC_SERVER,\
  14.                 IID_IPinnedList2,ppv2
  15.         cmp     eax,S_OK
  16.         jz      @f
  17.  
  18.         ; Попробовать создать объект (Vista)
  19.         invoke  CoCreateInstance,CLSID_TaskbarPin,NULL,\
  20.                 CLSCTX_INPROC_SERVER,\
  21.                 IID_IPinnedList,ppv1
  22.         cmp     eax,S_OK
  23.         jnz     loc_exit
  24. @@:
  25.         invoke  ILCreateFromPath,szLink
  26.         mov     [pEnum],eax
  27.  
  28. loc_pin1:
  29.         ; Windows Vista
  30.         cmp     [ppv1],0
  31.         jz      loc_pin2
  32.         ; Приложение уже закреплено на панели задач?
  33.         mov     eax, [ppv1]
  34.         mov     eax, [eax]
  35.         stdcall dword [eax+IPinnedList.IsPinned],\
  36.                 [ppv1],[pEnum]
  37.         cmp     eax,S_OK
  38.         jne     @f
  39.         ; Открепить приложение из панели задач
  40.         mov     eax, [ppv1]
  41.         mov     eax, [eax]
  42.         stdcall dword [eax+IPinnedList.Modify],\
  43.                 [ppv1],[pEnum],0
  44.         jmp     loc_done
  45. @@:
  46.         ; Закрепить приложение на панели задач
  47.         mov     eax, [ppv1]
  48.         mov     eax, [eax]
  49.         stdcall dword [eax+IPinnedList.Modify],\
  50.                 [ppv1],0,[pEnum]
  51.         jmp     loc_done
  52.  
  53. loc_pin2:
  54.         ; Windows 7, 8, 8.1
  55.         cmp     [ppv2],0
  56.         jz      loc_pin3
  57.         ; Приложение уже закреплено на панели задач?
  58.         mov     eax, [ppv2]
  59.         mov     eax, [eax]
  60.         stdcall dword [eax+IPinnedList2.IsPinned],\
  61.                 [ppv2],[pEnum]
  62.         cmp     eax,S_OK
  63.         jne     @f
  64.         ; Открепить приложение из панели задач
  65.         mov     eax, [ppv2]
  66.         mov     eax, [eax]
  67.         stdcall dword [eax+IPinnedList2.Modify],\
  68.                 [ppv2],[pEnum],0
  69.         jmp     loc_done
  70. @@:
  71.         ; Закрепить приложение на панели задач
  72.         mov     eax, [ppv2]
  73.         mov     eax, [eax]
  74.         stdcall dword [eax+IPinnedList2.Modify],\
  75.                 [ppv2],0,[pEnum]
  76.         jmp     loc_done
  77. loc_pin3:
  78.         ; Windows 10
  79.         cmp     [ppv3],0
  80.         jz      loc_exit
  81.         ; Приложение уже закреплено на панели задач?
  82.         mov     eax, [ppv3]
  83.         mov     eax, [eax]
  84.         stdcall dword [eax+IPinnedList3.IsPinned],\
  85.                 [ppv3],[pEnum]
  86.         cmp     eax,S_OK
  87.         jne     @f
  88.         ; Открепить приложение из панели задач
  89.         mov     eax, [ppv3]
  90.         mov     eax, [eax]
  91.         stdcall dword [eax+IPinnedList3.Modify],\
  92.                 [ppv3],[pEnum],0,PLMC_EXPLORER
  93.         jmp     loc_done
  94. @@:
  95.         ; Закрепить приложение на панели задач
  96.         mov     eax, [ppv3]
  97.         mov     eax, [eax]
  98.         stdcall dword [eax+IPinnedList3.Modify],\
  99.                 [ppv3],0,[pEnum],PLMC_EXPLORER
  100.  
  101. loc_done:
  102.         invoke  ILFree,[pEnum]
  103.  
  104.         ; Освободить объекты
  105.         cmp     [ppv1],0
  106.         jz      @f
  107.         mov     eax, [ppv1]
  108.         mov     eax, [eax]
  109.         stdcall dword [eax+IPinnedList.Release],[ppv1]
  110. @@:
  111.         cmp     [ppv2],0
  112.         jz      @f
  113.         mov     eax, [ppv2]
  114.         mov     eax, [eax]
  115.         stdcall dword [eax+IPinnedList2.Release],[ppv2]
  116. @@:
  117.         cmp     [ppv3],0
  118.         jz      @f
  119.         mov     eax, [ppv3]
  120.         mov     eax, [eax]
  121.         stdcall dword [eax+IPinnedList3.Release],[ppv3]
  122. @@:
  123.         ; Удалить объект
  124.         invoke  CoUninitialize
Как получить список программ, которые закреплены в панели задач? Очень просто, перебираете поочередно все .lnk-файлы в папке %APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar, это и есть искомый список. Но просто удалять их оттуда не вполне корректно, получив имя файла ярлыка его надо изымать из панели задач указанным выше способом. Иначе визуально значок останется на панели задач, но при попытке задействовать его, система выдаст следующее предупреждение:

Результат удаления ярлыка напрямую
Результат удаления ярлыка напрямую

В приложении примеры программ с исходными текстами, которые закрепляют ярлык стандартной игрушки Solitaire на панели задач, а затем изымают его оттуда.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Pin.Unpin.Shortcut.Demo.zip (4,253 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 1873 | Комментариев: 9

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (10.04.2021 в 21:55):
Добавлен пример добавления и удаления ярлыков с помощью COM-объектов. Архив обновлен.
Владимир (16.12.2016 в 21:01):
ManHunter, спасибо. Вроде работает.
ManHunter (13.12.2016 в 21:16):
http://rgho.st/62WHTBKfK

Цитатаесли можно, то с исходными текстами.

"Дайте воды попить, а то так есть хочется, что переночевать негде"
Владимир (13.12.2016 в 18:25):
ManHunter, да, меня интересует такая программа, и, если можно, то с исходными текстами.

Кстати, на Windows 8.1 я пробовал копировать SCF-файл из Windows XP, который это делает. Он работает, но не закрепляется в "Панели задач".
ManHunter (12.12.2016 в 23:20):
ЦитатаХотелось бы узнать как вернуть на "Панель задач" большую кнопку "Свернуть все окна"

У меня для этих целей написана специальная софтинка. Выложить?
Владимир (12.12.2016 в 22:17):
Хотелось бы узнать как вернуть на "Панель задач" большую кнопку "Свернуть все окна" (точно такую же как в Windows XP).

В смысле я знаю много способов как свернуть окна, но хотелось бы именно как в Windows XP (то есть рядом с кнопкой "Пуск", а не в "Области уведомлений").
ManHunter (05.10.2016 в 16:06):
Да, ошибся в тексте. Поправил, спасибо!
anonymous (05.10.2016 в 14:57):
"Результат выполнения не должен превышать 20h, это будет означать, что функция отработала успешно. Любое значение больше 20h считается ошибкой."

Наоборот, любое значение <= 20h считается ошибкой. Это видно даже из вашего кода.

cmp     eax,20h
ja      pinned_ok

cmp     eax,20h
ja      unpinned_ok
wetal (19.09.2016 в 19:12):
На Win10 этот способ почему то выпилили из системы. С другой стороны, оно и верно. А то всякие говнопрограмы лезли без спросу на панель. Только юзер вправе решать, кому там быть.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2021
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0047 сек.) / Память: 4.75 Mb
Наверх