
Как получить список ярлыков на рабочем столе

Как получить список ярлыков на рабочем столе
Если вы интересуетесь компьютерами и любите порядок в своем электронном хозяйстве, то наверняка встречали программы для сохранения и восстановления позиций ярлыков на рабочем столе. Судя по многочисленным отзывам пользователей на различных софтовых порталах и форумах, такие программы действительно востребованы. Давайте посмотрим, каким образом можно получить список и позиции ярлыков рабочего стола.
Начинаем с определения структур и констант, которые нам понадобятся для дальнейшей работы, но про которые FASM ничего не знает.
Code (Assembler) : Убрать нумерацию
- struct DECIMAL
- wReserved dw ?
- union
- struct
- scale db ?
- sign db ?
- ends
- signscale dw ?
- ends
- Hi32 dd ?
- union
- struct
- Lo32 dd ?
- Mid32 dd ?
- ends
- Lo64 dq ?
- ends
- ends
- struct VARIANT
- union
- struct
- vt dw ?
- wReserved rw 3
- union
- llVal dq ?
- lVal dd ?
- iVal dw ?
- bVal db ?
- ends
- ends
- decVal DECIMAL
- ends
- ends
- struct STRRET
- uType dd ?
- union
- pOleStr dd ?
- uOffset dd ?
- cStr rb 260
- ends
- ends
- CLSCTX_INPROC_SERVER = 0x01
- CLSCTX_INPROC_HANDLER = 0x02
- CLSCTX_LOCAL_SERVER = 0x04
- CLSCTX_REMOTE_SERVER = 0x10
- CLSCTX_SERVER = CLSCTX_INPROC_SERVER + CLSCTX_LOCAL_SERVER\
- + CLSCTX_REMOTE_SERVER
- CLSCTX_ALL = CLSCTX_INPROC_HANDLER + CLSCTX_SERVER
- S_OK = 0
- SWC_DESKTOP = 8
- SWFO_NEEDDISPATCH = 1
- CSIDL_DESKTOP = 0x0000
- SVGIO_ALLVIEW = 2
- SHGDN_NORMAL = 0
- VT_EMPTY = 0
- VT_NULL = 1
- VT_I2 = 2
- VT_I4 = 3
- VT_R4 = 4
- VT_R8 = 5
- VT_CY = 6
- VT_DATE = 7
- VT_BSTR = 8
- VT_DISPATCH = 9
- VT_ERROR = 10
- VT_BOOL = 11
- VT_VARIANT = 12
- VT_UNKNOWN = 13
- VT_DECIMAL = 14
- VT_I1 = 16
- VT_UI1 = 17
- VT_UI2 = 18
- VT_UI4 = 19
- VT_I8 = 20
- VT_UI8 = 21
- VT_INT = 22
- VT_UINT = 23
- VT_VOID = 24
- VT_HRESULT = 25
- VT_PTR = 26
- VT_SAFEARRAY = 27
- VT_CARRAY = 28
- VT_USERDEFINED = 29
- VT_LPSTR = 30
- VT_LPWSTR = 31
- VT_RECORD = 36
- VT_INT_PTR = 37
- VT_UINT_PTR = 38
- VT_FILETIME = 64
- VT_BLOB = 65
- VT_STREAM = 66
- VT_STORAGE = 67
- VT_STREAMED_OBJECT = 68
- VT_STORED_OBJECT = 69
- VT_BLOB_OBJECT = 70
- VT_CF = 71
- VT_CLSID = 72
- VT_VERSIONED_STREAM = 73
- VT_BSTR_BLOB = 0x0FFF
- VT_VECTOR = 0x1000
- VT_ARRAY = 0x2000
- VT_BYREF = 0x4000
- VT_RESERVED = 0x8000
- VT_ILLEGAL = 0xFFFF
- VT_ILLEGALMASKED = 0x0FFF
- VT_TYPEMASK = 0x0FFF
Code (Assembler) : Убрать нумерацию
- ; GUID {9BA05972-F6A8-11CF-A442-00A0C90A8F39}
- CLSID_ShellWindows dd 09BA05972h
- dw 0F6A8h
- dw 011CFh
- db 0A4h, 042h, 000h, 0A0h, 0C9h, 00Ah, 08Fh, 039h
- ; GUID {85CB6900-4D95-11CF-960C-0080C7F4EE85}
- IID_IShellWindows dd 085CB6900h
- dw 04D95h
- dw 011CFh
- db 096h, 00Ch, 000h, 080h, 0C7h, 0F4h, 0EEh, 085h
- ; GUID {4C96BE40-915C-11CF-99D3-00AA004AE837}
- CLSID_STopLevelBrowser dd 04C96BE40h
- dw 0915Ch
- dw 011CFh
- db 099h, 0D3h, 000h, 0AAh, 000h, 04Ah, 0E8h, 037h
- ; GUID {000214E2-0000-0000-C000-000000000046}
- IID_IShellBrowser dd 0000214E2h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; GUID {CDE725B0-CCC9-4519-917E-325D72FAB4CE}
- IID_IFolderView dd 0CDE725B0h
- dw 0CCC9h
- dw 04519h
- db 091h, 07Eh, 032h, 05Dh, 072h, 0FAh, 0B4h, 0CEh
- ; GUID {000214E6-0000-0000-C000-000000000046}
- IID_IShellFolder dd 0000214E6h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; GUID {000214F2-0000-0000-C000-000000000046}
- IID_IEnumIDList dd 0000214F2h
- dw 00000h
- dw 00000h
- db 0C0h, 000h, 000h, 000h, 000h, 000h, 000h, 046h
- ; IID_IShellWindows Interface
- struct IShellWindows
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetTypeInfoCount dd ?
- GetTypeInfo dd ?
- GetIDsOfNames dd ?
- _Invoke dd ?
- ; Properties
- get_Count dd ?
- ; IShellWindows
- Item dd ?
- _NewEnum dd ?
- Register dd ?
- RegisterPending dd ?
- Revoke dd ?
- OnNavigate dd ?
- OnActivated dd ?
- FindWindowSW dd ?
- OnCreated dd ?
- ProcessAttachDetach dd ?
- ends
- ; IID_IShellBrowser Interface
- struct IShellBrowser
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetWindow dd ?
- ContextSensitiveHelp dd ?
- InsertMenusSB dd ?
- SetMenuSB dd ?
- RemoveMenusSB dd ?
- SetStatusTextSB dd ?
- EnableModelessSB dd ?
- TranslateAcceleratorSB dd ?
- BrowseObject dd ?
- GetViewStateStream dd ?
- GetControlWindow dd ?
- SendControlMsg dd ?
- QueryActiveShellView dd ?
- OnViewWindowActive dd ?
- SetToolbarItems dd ?
- ends
- ; IID_IShellFolder Interface
- struct IShellFolder
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ParseDisplayName dd ?
- EnumObjects dd ?
- BindToObject dd ?
- BindToStorage dd ?
- CompareIDs dd ?
- CreateViewObject dd ?
- GetAttributesOf dd ?
- GetUIObjectOf dd ?
- GetDisplayNameOf dd ?
- SetNameOf dd ?
- ends
- ; IID_IFolderView Interface
- struct IFolderView
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- GetCurrentViewMode dd ?
- SetCurrentViewMode dd ?
- GetFolder dd ?
- Item dd ?
- ItemCount dd ?
- Items dd ?
- GetSelectionMarkedItem dd ?
- GetFocusedItem dd ?
- GetItemPosition dd ?
- GetSpacing dd ?
- GetDefaultSpacing dd ?
- GetAutoArrange dd ?
- SelectItem dd ?
- SelectAndPositionItems dd ?
- ends
- ; IID_IEnumIDList Interface
- struct IEnumIDList
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- Next dd ?
- Skip dd ?
- Reset dd ?
- Clone dd ?
- ends
- struct IUnknown
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ends
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Создать объект
- invoke CoCreateInstance,CLSID_ShellWindows,NULL,\
- CLSCTX_ALL,IID_IShellWindows,pISwDisp
- cmp eax,S_OK
- jne loc_exit
- ; Найти окно рабочего стола и получить интерфейс
- ; для работы с ним
- mov [varLoc.vt],VT_I4
- mov [varLoc.lVal],CSIDL_DESKTOP
- mov [varLocRoot.vt],VT_EMPTY
- mov eax,[pISwDisp]
- mov eax,[eax]
- stdcall dword [eax+IShellWindows.FindWindowSW],[pISwDisp],varLoc,\
- varLocRoot,SWC_DESKTOP,hwnd,SWFO_NEEDDISPATCH,spdisp
- invoke IUnknown_QueryService,[spdisp],CLSID_STopLevelBrowser,\
- IID_IShellBrowser,spBrowser
- mov eax,[spBrowser]
- mov eax,[eax]
- stdcall dword [eax+IShellBrowser.QueryActiveShellView],\
- [spBrowser],spshView
- mov eax,[spshView]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder.QueryInterface],[spshView],\
- IID_IFolderView,spView
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.GetFolder],[spView],\
- IID_IShellFolder,spFolder
- ; Получить список объектов
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.Items],[spView],SVGIO_ALLVIEW,\
- IID_IEnumIDList,spEnum
- loc_loop:
- ; Получить следующий объект рабочего стола
- mov eax,[spEnum]
- mov eax,[eax]
- stdcall dword [eax+IEnumIDList.Next],[spEnum],1,spidl,0
- or eax,eax
- jne loc_done
- ; Получить название иконки
- mov eax,[spFolder]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder.GetDisplayNameOf],[spFolder],\
- [spidl],SHGDN_NORMAL,strRet
- ; Преобразовать его в привычный вид
- invoke StrRetToStr,strRet,[spidl],spszName
- ; Получить координаты иконки
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.GetItemPosition],[spView],\
- [spidl],pt
- ; [spszName] --> указатель на строку названия ярлыка
- ; pt --> координаты ярлыка относительно левого верхнего угла
- ...
- ...
- jmp loc_loop
- loc_done:
- ; Прибраться за собой
- mov eax,[spEnum]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spEnum]
- mov eax,[spFolder]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spFolder]
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spView]
- mov eax,[spshView]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spshView]
- mov eax,[spBrowser]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spBrowser]
- mov eax,[spdisp]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[spdisp]
- mov eax,[pISwDisp]
- mov eax,[eax]
- stdcall dword [eax+IUnknown.Release],[pISwDisp]
- ; Удалить объект
- invoke CoUninitialize
Code (Assembler) : Убрать нумерацию
- SVSI_POSITIONITEM = 0x80
- ; Установить новые координаты иконки
- mov eax,[spView]
- mov eax,[eax]
- stdcall dword [eax+IFolderView.SelectAndPositionItems],[spView],\
- 1,spidl,pt,SVSI_POSITIONITEM
В приложении пример программы с исходным текстом, которая выводит список ярлыков рабочего стола с их координатами.
Просмотров: 1344 | Комментариев: 7

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(09.08.2020 в 11:25):
Проактивка антивирусов может не одобрить такого поведения.

wet
(09.08.2020 в 09:24):
Можно попроще сделать. Найти pid проводника GetWindowThreadProcessId,
подключится к процессу OpenProcess, скопировать структуру LV_ITEM WriteProcessMemory в выделенную для этого память VirtualAllocEx.
А дальше SendMessage к Desktop Handle:
LVM_GETITEMCOUNT общее кол-во иконок
LVM_GETITEMTEXT их имена
LVM_GETITEMPOSITION их координаты.
подключится к процессу OpenProcess, скопировать структуру LV_ITEM WriteProcessMemory в выделенную для этого память VirtualAllocEx.
А дальше SendMessage к Desktop Handle:
LVM_GETITEMCOUNT общее кол-во иконок
LVM_GETITEMTEXT их имена
LVM_GETITEMPOSITION их координаты.

Василий
(06.08.2020 в 12:46):
ManHunter, такого годного контента ещё поискать... очень хорошие статьи, не вздумай бросать)))

Евгений
(05.08.2020 в 13:08):
"Может оно и не надо совсем?" - несогласен, нужно посмотреть на кнопочку "сказать спасибо!".

0101
(05.08.2020 в 10:30):
похоже). Как им бабки зарабатывать? В интсте/ютубе за просмотры и лайки капает денежка! И мозги не напрягаются. Кайми вот в бизнес подался.. Имхо:
1. давно уже надо/пора выдрать файлы костант и структур (из других ЯП), чтобы вообще о них не думать и подключать инкудом.
2. без макросов select/case, прямого сравнения (>=<) и присвоения данных/строк (без постоянного дёрганья eax), объявления строк и переменных "по месту" - совсем скучно. Форки asm'а это давно могут.
3. меня раздражают скобки вместо @/&/*, инвоки, отсутствие процедур - код нечитаем с этими @f/ret.
4. секция ресурсов не наглядна. Почему бы не нарисовать диалоговое окно в ResEd и затем прилинковать? Знаю, есть прога, которые из *.rc переводят в формат ресурсов fasm.. Ты их используешь или из головы сразу пишешь такие большие ресурсы?
5.FASMW в качестве IDE не подходит - нет подсветки и автокомплита. Надо или RadAsm/EasyCode продвигать или к npp автокомплит прикручивать (подходит от RadAsm с небольшими правками) или твой Sublime расшаривать..
6. нужны исходники - литература, откуда всё (идеи статей) взялось, даже на английском. Кому-то проще в си-коде разбираться, кому-то (мне) хотелось бы не просто на код посмотреть, но и теорию почитать. Например: в теме "Создание и обработка улучшенного MessageBox" хотелось бы почитать теорию по хукам или о том, что у MsgBox есть (независимое) текстовое поле со своим хендлом.. Статьи (мне) не достаточно для понимания, приходится гуглить (копаться в chm-форуме RDSN за 2007г..) аналогичные примеры..
1. давно уже надо/пора выдрать файлы костант и структур (из других ЯП), чтобы вообще о них не думать и подключать инкудом.
2. без макросов select/case, прямого сравнения (>=<) и присвоения данных/строк (без постоянного дёрганья eax), объявления строк и переменных "по месту" - совсем скучно. Форки asm'а это давно могут.
3. меня раздражают скобки вместо @/&/*, инвоки, отсутствие процедур - код нечитаем с этими @f/ret.
4. секция ресурсов не наглядна. Почему бы не нарисовать диалоговое окно в ResEd и затем прилинковать? Знаю, есть прога, которые из *.rc переводят в формат ресурсов fasm.. Ты их используешь или из головы сразу пишешь такие большие ресурсы?
5.FASMW в качестве IDE не подходит - нет подсветки и автокомплита. Надо или RadAsm/EasyCode продвигать или к npp автокомплит прикручивать (подходит от RadAsm с небольшими правками) или твой Sublime расшаривать..
6. нужны исходники - литература, откуда всё (идеи статей) взялось, даже на английском. Кому-то проще в си-коде разбираться, кому-то (мне) хотелось бы не просто на код посмотреть, но и теорию почитать. Например: в теме "Создание и обработка улучшенного MessageBox" хотелось бы почитать теорию по хукам или о том, что у MsgBox есть (независимое) текстовое поле со своим хендлом.. Статьи (мне) не достаточно для понимания, приходится гуглить (копаться в chm-форуме RDSN за 2007г..) аналогичные примеры..

A1eksandr1
(05.08.2020 в 04:21):
Ну некоторые всё же почитывают. А комментировать/дискутировать - это уже совсем другая история)
Ещё и публикации появляются задним числом (дата статьи: 25.07; по факту отобразилась только 04.08), не каждый откроет, если не будет пролистывать блог вниз.
Ещё и публикации появляются задним числом (дата статьи: 25.07; по факту отобразилась только 04.08), не каждый откроет, если не будет пролистывать блог вниз.

ManHunter
(04.08.2020 в 23:12):
Похоже, что популяризация Ассемблера проходит мимо. Может оно и не надо совсем? Завести инстаграмм, постить фотки пюрешки с сосисками...

Добавить комментарий
Заполните форму для добавления комментария
