Blog. Just Blog

Программное удаление файла в Корзину

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Небольшой сниппет - удаление файла или группы файлов в Корзину. Делается это при помощи функции SHFileOperation, но сперва нам надо будет определить необходимую структуру SHFILEOPSTRUCT и несколько констант.
  1. struct SHFILEOPSTRUCT
  2.         hwnd                  dd ?
  3.         wFunc                 dd ?
  4.         pFrom                 dd ?
  5.         pTo                   dd ?
  6.         fFlags                dw ?
  7.         fAnyOperationsAborted dd ?
  8.         hNameMappings         dd ?
  9.         lpszProgressTitle     dd ?
  10. ends
  11.  
  12. FO_DELETE = 3h
  13.  
  14. FOF_ALLOWUNDO      = 40h
  15. FOF_NOCONFIRMATION = 10h
  16. FOF_SILENT         = 4h
Сам код очень простой. Указываем тип операции FO_DELETE, то есть удаление, в параметре pFrom передаем список объектов на удаление, флагами настраиваем поведение - удалять с возможностью отката (то есть в Корзину), не показывать никаких подтверждений и диалогов.
  1.         mov     [fos.hwnd],HWND_DESKTOP
  2.         mov     [fos.wFunc],FO_DELETE
  3.         mov     [fos.pFrom],fname
  4.         mov     [fos.fFlags],FOF_ALLOWUNDO+FOF_NOCONFIRMATION+FOF_SILENT
  5.         invoke  SHFileOperation,fos
Обратите внимание, что список объектов должен заканчиваться двойным нулевым символом, даже если удаляется один файл. Также при удалении файлов со съемных носителей они могут удаляться без попадания в Корзину, но это как и при удалении через Проводник Windows.

Начиная с Windows Vista, файловые операции через функцию SHFileOperation считаются устаревшими, и Microsoft рекомендует использовать вместо них операции через COM-объекты. Неизбежно это тянет за собой тонну писанины: идентификаторы, интерфейсы, константы, достаточно объемный код реализации.
  1. ; GUID {3AD05575-8857-4850-9277-11B85BDB8E09}
  2. CLSID_FileOperation dd 03AD05575h
  3.                     dw 08857h
  4.                     dw 04850h
  5.                     db 092h, 077h, 011h, 0B8h, 05Bh, 0DBh, 08Eh, 009h
  6.  
  7. ; GUID {947AAB5F-0A5C-4C13-B4D6-4BF7836FC9F8}
  8. IID_IFileOperation  dd 0947AAB5Fh
  9.                     dw 00A5Ch
  10.                     dw 04C13h
  11.                     db 0B4h, 0D6h, 04Bh, 0F7h, 083h, 06Fh, 0C9h, 0F8h
  12.  
  13. ; GUID {43826D1E-E718-42EE-BC55-A1E261C37BFE}
  14. IID_IShellItem      dd 043826D1Eh
  15.                     dw 0E718h
  16.                     dw 042EEh
  17.                     db 0BCh, 055h, 0A1h, 0E2h, 061h, 0C3h, 07Bh, 0FEh
  18.  
  19. ; IID_IFileOperation Interface
  20. struct IFileOperationDispatch
  21.     QueryInterface          dd ?
  22.     AddRef                  dd ?
  23.     Release                 dd ?
  24.  
  25.     ; IFileOperation
  26.     Advise                  dd ?
  27.     Unadvise                dd ?
  28.     SetOperationFlags       dd ?
  29.     SetProgressMessage      dd ?
  30.     SetProgressDialog       dd ?
  31.     SetProperties           dd ?
  32.     SetOwnerWindow          dd ?
  33.     ApplyPropertiesToItem   dd ?
  34.     ApplyPropertiesToItems  dd ?
  35.     RenameItem              dd ?
  36.     RenameItems             dd ?
  37.     MoveItem                dd ?
  38.     MoveItems               dd ?
  39.     CopyItem                dd ?
  40.     CopyItems               dd ?
  41.     DeleteItem              dd ?
  42.     DeleteItems             dd ?
  43.     NewItem                 dd ?
  44.     PerformOperations       dd ?
  45.     GetAnyOperationsAborted dd ?
  46. ends
  47.  
  48. CLSCTX_INPROC_SERVER    = 1
  49. S_OK                    = 0
Сам код удаления будет включать несколько шагов, помимо стандартных операций с COM-объектами. Сперва устанавливаются флаги операции, к счастью, они совпадают с флагами SHFileOperation. Затем из имени файла надо создать COM-объект типа IShellItem, потому что методы объекта IFileOperation умеют работать только с такими сущностями. После этого выбирается тип выполняемой операции - удаление файла. И только выполнив все эти приготовления, можно будет выполнить саму операцию. На мой взгляд, замена одной функции подобной свистопляской - такое себе "удобство".
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.         ; Создать объект
  4.         invoke  CoCreateInstance,CLSID_FileOperation,NULL,\
  5.                 CLSCTX_INPROC_SERVER,\
  6.                 IID_IFileOperation,pIFoDisp
  7.         cmp     eax,S_OK
  8.         jne     loc_exit
  9.  
  10.         ; Установить флаги выполняемой операции
  11.         mov     eax, [pIFoDisp]
  12.         mov     eax, [eax]
  13.         stdcall dword [eax+IFileOperationDispatch.SetOperationFlags],\
  14.                 [pIFoDisp],FOF_ALLOWUNDO+FOF_NOCONFIRMATION+FOF_SILENT
  15.  
  16.         ; Создать объект IShellItem из пути к файлу
  17.         invoke  SHCreateItemFromParsingName,filename,NULL,IID_IShellItem,\
  18.                 deleteItem
  19.  
  20.         ; Подготовить операцию удаления файла
  21.         mov     eax, [pIFoDisp]
  22.         mov     eax, [eax]
  23.         stdcall dword [eax+IFileOperationDispatch.DeleteItem],\
  24.                 [pIFoDisp],[deleteItem],NULL
  25.  
  26.         ; Выполнить операцию
  27.         mov     eax, [pIFoDisp]
  28.         mov     eax, [eax]
  29.         stdcall dword [eax+IFileOperationDispatch.PerformOperations],[pIFoDisp]
  30.  
  31.         ; Прибраться за собой
  32.         mov     eax, [pIFoDisp]
  33.         mov     eax, [eax]
  34.         stdcall dword [eax+IFileOperationDispatch.Release],[pIFoDisp]
  35.  
  36.         ; Удалить объект
  37.         invoke  CoUninitialize
Из дополнительных особенностей стоит отметить, что методы IFileOperation работают исключительно с юникодными строками, а путь к файлу при преобразовании в объект должен быть полным, то есть включать в себя и название каталога. Столько лишних движений ради простейшей операции.

Если возможность восстановления не важна, то в остальных случаях для удаления файлов лучше все-таки использовать функцию DeleteFile.

В приложении примеры программ с исходными текстами, которые создают временный файл "test.txt", а затем удаляют его в Корзину разными способами.

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

Delete.to.Recycle.Bin.Demo.zip (3,757 bytes)


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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (26.08.2020 в 16:37):
Добавил реализацию удаления через COM-объекты. Архив обновлен.

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

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

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