Blog. Just Blog

Как программно получить и установить рейтинг файла

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

Начиная с Windows Vista у пользователя появилась возможность ставить оценки некоторым файлам, например, фотографиям, музыкальным файлам и видеороликам. Оценка отображается при просмотре таблицы файлов в Проводнике в виде звездного рейтинга от 0 до 5. На мой взгляд, штука не особо нужная, но раз она присутствует в системе, то почему бы не научиться с ней работать? Как обычно, Ассемблер нам в этом поможет.

Поскольку здесь используются COM-объекты, нам понадобится некоторое количество структур, интерфейсов и констант для работы. Все как всегда, ничего необычного.
  1. struct PROPVARIANT
  2.     vt        dw ?
  3.     wReserved rw 3
  4.     struct
  5.         lVal  dd ?
  6.     ends
  7.     decVal    dd ?
  8. ends
  9.  
  10. struct PROPKEY
  11.      fmtid rb 16
  12.      pid   dd ?
  13. ends
  14.  
  15. ; IID_IShellItem2 Interface
  16. struct IShellItem2
  17.     ; IUnknown
  18.     QueryInterface                   dd ?   ; 000h
  19.     AddRef                           dd ?   ; 004h
  20.     Release                          dd ?   ; 008h
  21.     ; IShellItem2
  22.     BindToHandler                    dd ?   ; 00Ch
  23.     GetParent                        dd ?   ; 010h
  24.     GetDisplayName                   dd ?   ; 014h
  25.     GetAttributes                    dd ?   ; 018h
  26.     Compare                          dd ?   ; 01Ch
  27.     GetPropertyStore                 dd ?   ; 020h
  28.     GetPropertyStoreWithCreateObject dd ?   ; 024h
  29.     GetPropertyStoreForKeys          dd ?   ; 028h
  30.     GetPropertyDescriptionList       dd ?   ; 02Ch
  31.     Update                           dd ?   ; 030h
  32.     GetProperty                      dd ?   ; 034h
  33.     GetCLSID                         dd ?   ; 038h
  34.     GetFileTime                      dd ?   ; 03Ch
  35.     GetInt32                         dd ?   ; 040h
  36.     GetString                        dd ?   ; 044h
  37.     GetUInt32                        dd ?   ; 048h
  38.     GetUInt64                        dd ?   ; 04Ch
  39.     GetBool                          dd ?   ; 050h
  40. ends
  41.  
  42. ; IID_IPropertyStore Interface
  43. struct IPropertyStore
  44.     ; IUnknown
  45.     QueryInterface dd ?   ; 000h
  46.     AddRef         dd ?   ; 004h
  47.     Release        dd ?   ; 008h
  48.     ; IPropertyStore
  49.     GetCount       dd ?   ; 00Ch
  50.     GetAt          dd ?   ; 010h
  51.     GetValue       dd ?   ; 014h
  52.     SetValue       dd ?   ; 018h
  53.     Commit         dd ?   ; 01Ch
  54. ends
  55.  
  56. ; GUID {7E9FB0D3-919F-4307-AB2E-9B1860310C93}
  57. IID_IShellItem2 \
  58.     dd 07E9FB0D3h
  59.     dw 0919Fh
  60.     dw 04307h
  61.     db 0ABh, 02Eh, 09Bh, 018h, 060h, 031h, 00Ch, 093h
  62.  
  63. ; GUID {886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}
  64. IID_IPropertyStore \
  65.     dd 0886D8EEBh
  66.     dw 08CF2h
  67.     dw 04446h
  68.     db 08Dh, 002h, 0CDh, 0BAh, 01Dh, 0BDh, 0CFh, 099h
  69.  
  70. ; GUID {64440492-4C8B-11D1-8B70-080036B11A03}
  71. PKEY_Rating \
  72.     dd 064440492h
  73.     dw 04C8Bh
  74.     dw 011D1h
  75.     db 08Bh, 070h, 008h, 000h, 036h, 0B1h, 01Ah, 003h
  76. PKEY_Rating_pid = 9
  77.  
  78. VT_UI4 = 19
  79. GPS_READWRITE = 2
В прошлый раз доступ к свойствам файла я реализовывал при помощи пары функций SHGetPropertyStoreFromParsingName и PSGetPropertySystem, сегодня для разнообразия воспользуюсь функцией ILCreateFromPath для создания списка ITEMIDLIST, функцией SHCreateItemFromIDList для получения объекта IShellItem2 и его методом GetPropertyStore для доступа к хранилищу.

Получив объект хранилища свойств файла, можно или получить нужное значение, или же установить его новое значение. В нашем случае это будет свойство PKEY_Rating. Начнем с получения текущего значения рейтинга файла.
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.  
  4.         ; Получить полный путь к файлу
  5.         invoke  GetFullPathName,fname,MAX_PATH,szPath,NULL
  6.         or      eax,eax
  7.         jz      loc_exit
  8.  
  9.         ; Создать структуру ITEMIDLIST
  10.         invoke  ILCreateFromPath,szPath
  11.         or      eax,eax
  12.         jz      loc_exit
  13.  
  14.         mov     [pidlFile],eax
  15.  
  16.         ; Создать объект IShellItem2
  17.         invoke  SHCreateItemFromIDList,[pidlFile],IID_IShellItem2,pShItem
  18.         or      eax,eax
  19.         jnz     loc_exit
  20.  
  21.         ; Получить интерфейс IPropertyStore объекта
  22.         mov     eax,[pShItem]
  23.         mov     eax,[eax]
  24.         stdcall dword [eax+IShellItem2.GetPropertyStore],[pShItem],\
  25.                 GPS_READWRITE,IID_IPropertyStore,pPropStore
  26.         or      eax,eax
  27.         jnz     loc_done2
  28.  
  29.         ; Заполнить структуру PROPKEY
  30.         mov     edi,prop.fmtid
  31.         mov     esi,PKEY_Rating
  32.         movsd
  33.         movsd
  34.         movsd
  35.         movsd
  36.         mov     [prop.pid],PKEY_Rating_pid
  37.  
  38.         ; Получить текущее значение рейтинга
  39.         mov     eax,[pPropStore]
  40.         mov     eax,[eax]
  41.         stdcall [eax+IPropertyStore.GetValue],[pPropStore],prop,variant
  42.         or      eax,eax
  43.         jnz     loc_done1
  44.  
  45.         ; [variant.lVal] = значение рейтинга 0..99
  46.  
  47. loc_done1:
  48.         ; Прибраться за собой
  49.         mov     eax,[pPropStore]
  50.         mov     eax,[eax]
  51.         stdcall [eax+IPropertyStore.Release],[pPropStore]
  52. loc_done2:
  53.         mov     eax,[pShItem]
  54.         mov     eax,[eax]
  55.         stdcall [eax+IShellItem2.Release],[pShItem]
  56. loc_exit:
  57.         ; Удалить объект
  58.         invoke  CoUninitialize
Если все отработает успешно, то в поле lVal структуры PROPVARIANT будет записано число в интервале 0..99, соответствующее установленному рейтингу файла.

Для установки нового значения рейтинга надо воспользоваться методом SetValue объекта хранилища свойств. Новое значение должно быть в интервале 0..99, иначе метод вернет ошибку. Для каждого рейтинга диапазоны будут следующие: [0] = нет оценки, [1..12] = 1 звезда, [13..37] = 2 звезды, [38..62] = 3 звезды, [63..87] = 4 звезды, [88..99] = 5 звезд. Кроме того, при помощи ручного способа установки можно задавать произвольное значение из разрешенного диапазона, тогда как при изменении рейтинга через Проводник будет установлено фиксированное значение 0, 1, 25, 50, 75 или 99 соответственно. Код установки рейтинга файла будет следующим:
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.  
  4.         ; Получить полный путь к файлу
  5.         invoke  GetFullPathName,fname,MAX_PATH,szPath,NULL
  6.         or      eax,eax
  7.         jz      loc_exit
  8.  
  9.         ; Создать структуру ITEMIDLIST
  10.         invoke  ILCreateFromPath,szPath
  11.         or      eax,eax
  12.         jz      loc_exit
  13.  
  14.         mov     [pidlFile],eax
  15.  
  16.         ; Создать объект IShellItem2
  17.         invoke  SHCreateItemFromIDList,[pidlFile],IID_IShellItem2,pShItem
  18.         or      eax,eax
  19.         jnz     loc_exit
  20.  
  21.         ; Получить интерфейс IPropertyStore объекта
  22.         mov     eax,[pShItem]
  23.         mov     eax,[eax]
  24.         stdcall dword [eax+IShellItem2.GetPropertyStore],[pShItem],\
  25.                 GPS_READWRITE,IID_IPropertyStore,pPropStore
  26.         or      eax,eax
  27.         jnz     loc_done2
  28.  
  29.         ; Заполнить структуру PROPKEY
  30.         mov     edi,prop.fmtid
  31.         mov     esi,PKEY_Rating
  32.         movsd
  33.         movsd
  34.         movsd
  35.         movsd
  36.         mov     [prop.pid],PKEY_Rating_pid
  37.  
  38.         ; Новое значение рейтинга 0..99
  39.         mov     [variant.vt],VT_UI4
  40.         mov     [variant.lVal],67  ; <- значение
  41.  
  42.         ; Установить новое значение рейтинга
  43.         mov     eax,[pPropStore]
  44.         mov     eax,[eax]
  45.         stdcall [eax+IPropertyStore.SetValue],[pPropStore],prop,variant
  46.         or      eax,eax
  47.         jnz     loc_done1
  48.  
  49.         ; Применить изменения
  50.         mov     eax,[pPropStore]
  51.         mov     eax,[eax]
  52.         stdcall [eax+IPropertyStore.Commit],[pPropStore]
  53.         or      eax,eax
  54.         jnz     loc_done1
  55.  
  56.         ; Новое значение рейтинга успешно установлено
  57.  
  58. loc_done1:
  59.         ; Прибраться за собой
  60.         mov     eax,[pPropStore]
  61.         mov     eax,[eax]
  62.         stdcall [eax+IPropertyStore.Release],[pPropStore]
  63. loc_done2:
  64.         mov     eax,[pShItem]
  65.         mov     eax,[eax]
  66.         stdcall [eax+IShellItem2.Release],[pShItem]
  67. loc_exit:
  68.         ; Удалить объект
  69.         invoke  CoUninitialize
Как я уже говорил, далеко не всем файлам можно поставить оценку. Если выбранный тип файла не поддерживает установку рейтинга, то метод GetPropertyStore вернет ошибку.

Рейтинг файла в Проводнике
Рейтинг файла в Проводнике

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

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

File.Rating.Demo.zip (5,528 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 428 | Комментариев: 0

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

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

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

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

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