История написания программки для удаления ненужных файлов

Привет, пользователи хабра! Хочу поделиться историей написания небольшой программки, которая удаляет ненужные файлы из выбранной директории.

Я пользуюсь Windows 7 и Google Chrome. Скачиваю в основном фильмы, но в сети часто встречается еще много чего интересного. Мне удобно когда свежие файлы находятся сразу под рукой на рабочем столе. А дальше полезные распределяю по назначению, остальные — в мусор. Поэтому директорией по умолчанию для загрузки в Chrome указал рабочий стол. Пользусь торрентами и торент файлы безжалостно захламляли рабочий стол, и удалять их вручную не было ни малейшего желания. Решил написать утилитку, которая будет удалять мусор с рабочего стола в фоновом режиме. Сначала реализовал в виде сервиса, но как оказалось с ним есть некоторые сложности при передаче сообщений системе, если он запускается под другим пользователем. Решил что аккуратненькая иконка в трее выглядит веселее и удобнее, поэтому от севиса в последствии отказался.

В библиотеке .NET framework'а есть полезный класс FileWatcher, который позволяет мониторить файлы в выбранной директории и реагировать на выбранные события по заданному фильтру:

// Establish the path to the directory to watch
FileSystemWatcher watcher = new FileSystemWatcher
{
 Path = (string)settingsReader.GetValue("watchDirectory", typeof(string)),
 NotifyFilter = NotifyFilters.FileName
};

// Add event handlers.
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;



Столкнулся с проблеммой что иконки файлов после удаления оставались на рабочем столе. Нажатия клавиши F5 огорчали не меньше чем удаление этих файлов в ручную. Пришлось найти способ тонко намекнуть системе что файлы были удалены и нужно обновить их отображение. Заветное решение находилось в системной библиотеке Shell32. Раньше никогда не сталкивался с вызовом нативного кода, но когда-то слышал про DllImport. Для нужного результата достаточно импортировать метод из указанной библиотеки и указать в параметрах константу которая сообщает системе что файл удален и путь к этому файлу. Чуток поковыряв Interop services получил вот такой аккуратный метод.

// Constants describes events for notifying
const uint SHCNE_DELETE = 0x00000004;
const uint SHCNF_PATH = 0x0005;

[DllImport("Shell32.dll")]
static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

void NotifyDelete(FileInfo fileInfo)
{
  // Noyify system that file was deleted
  IntPtr pathPtr = Marshal.StringToCoTaskMemAuto(fileInfo.FullName);
  SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, pathPtr, IntPtr.Zero);
  Marshal.FreeCoTaskMem(pathPtr);
  fileInfo.Refresh();
}


Программка заработала но периодически пропускала файлы. Какое-то время мне нужно было чтобы понять что Chrome просто не сообщает системе что файл был переименован. Получалось что чистка проводилась еще до того как файл был полностью скачан и он оставался огурцом. Решил проблему «засыпанием» потока пока файл не скачается. Соответственно теперь нужно организовать работу в многопоточном режиме чтобы зачистка продолжалась и во время скачивания чего-то тяжеленького.

Для того чтобы новый торрент-файл не удалялся еще до запуска но и не мешался на рабочем столе я решил новый скачанный файл просто делать невидимым до последующей чистки.

В итоге получилась простая программка, которая помогла мне пощупать разные технологии. Такое себе сочитание полезного и прияного. Если для кого-то она тоже окажется полезной скачать ее можно здесь, только нужно в файле настройки указать свою директорию.

Всем приятного новогоднего настроения!


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.