IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

 
 Ответить  Открыть новую тему 
> Перехватить переименование файла
Unconnected
сообщение 11.06.2010 22:56
Сообщение #1


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Привет всем.

Допустим, есть файл или папка, путь и имя известны. Нужно отловить событие переименования этого файла или папки и получить новое имя. Такое возможно?


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 12.06.2010 0:29
Сообщение #2


Гость






Можно. С помощью функции MSDN -> ReadDirectoryChangesW, например.

Вот тут есть пример использования. Но он не совсем корректен, потому что вот так smile.gif
 К началу страницы 
+ Ответить 
Unconnected
сообщение 12.06.2010 23:59
Сообщение #3


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Я немного изменил процедуру (убрал ненужные фильтры), получилось так:

type
PFileNotifyInformation = ^TFileNotifyInformation;
TFileNotifyInformation = record
NextEntryOffset: DWORD;
Action: DWORD;
FileNameLength: DWORD;
FileName: array [0..MAX_PATH - 1] of WideChar;
end;

var writepath:string;//нужное мне имя папки

Procedure monitor1(direc:string);
const
Filter = FILE_NOTIFY_CHANGE_FILE_NAME or
FILE_NOTIFY_CHANGE_DIR_NAME or
FILE_NOTIFY_CHANGE_CREATION or
FILE_NOTIFY_CHANGE_SECURITY;
var
Dir: THandle;
Notify: TFileNotifyInformation;
BytesReturned: DWORD;
newname:string;
begin
Dir := CreateFile(pchar(direc), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if Dir <> INVALID_HANDLE_VALUE then
try
if not ReadDirectoryChangesW(Dir, @Notify, SizeOf(TFileNotifyInformation),
False, Filter, @BytesReturned, nil, nil) then
raise Exception.Create(SysErrorMessage(GetLastError))
else
case Notify.Action of
FILE_ACTION_RENAMED_NEW_NAME: newname:=notify.FileName;
end;
renamefile(newname,writepath);
finally
CloseHandle(Dir);
end;
end;
...
begin
monitor(writepath);
end.



, оставил те, которые не знаю, зачем нужны) В процедуру передаю путь к папке, имя которой надо мониторить. Кстати, в msdn написано: The function does not report changes to the specified directory itself. Это случаем не значит, что программа не будет смотреть изменения папки, в которой сама находится? (да, знаю, что в большинстве случаев переименовать папку с работающей программой внутри не получится).
Так вот, запускаю её единожды - программа виснет. В таймере если запускать, тоже виснет. Как надо?

Добавлено через 15 мин.
Цитата
Это случаем не значит, что программа не будет смотреть изменения папки, в которой сама находится?


Даа, кажется именно это и значит..


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 13.06.2010 0:41
Сообщение #4


Гость






Цитата
Так вот, запускаю её единожды - программа виснет
Что значит "виснет"? У тебя синхронный вызов, пока событие, которое программа должна отловить, не произойдет, программа дальше не двинется. Сделай асинхронный - не будет зависать. В MSDN написано, что надо для этого сделать...
 К началу страницы 
+ Ответить 
volvo
сообщение 14.06.2010 10:57
Сообщение #5


Гость






Пример использования ReadDirectoryChangesW в отдельном потоке:


Прикрепленные файлы
Прикрепленный файл  spy_dir.zip ( 4.35 килобайт ) Кол-во скачиваний: 147
 К началу страницы 
+ Ответить 
Unconnected
сообщение 14.06.2010 12:57
Сообщение #6


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


У меня D2007 этот проект не открыла, говорит, там файла какого-то не хватает. Я аккуратно перенёс всё в новый проект, вписал нужный путь (такой файл существует), при нажатии "Начать" ошибка "файл не найден" не выдаётся, но и слежения, как я понял, не происходит (в Memo не появляются записи о переименовании, удалении и т.п.). Прикладываю на всякий случай мой проект, хотя там всё то же самое.



--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.06.2010 13:08
Сообщение #7


Гость






Цитата
говорит, там файла какого-то не хватает
Какого именно, можешь уточнить? Я делал под D2009, там работает. Твой код тоже отрабатывает:
Прикрепленное изображение


Добавлено через 2 мин.
P.S. Какая ОС, уточни, кстати. Может это опять Вистовские заморочки? И еще одно: что у тебя возвращает ReadDirectoryChangesW? Если False, то проверь причину:
    if not ReadDirectoryChangesW(hDir, lpBuf, BUFFER, true, Filter, @cbReturn, nil, nil) then
begin
ShowMessage(SysErrorMessage(GetLastError)); // Вот так
Break;
end;
 К началу страницы 
+ Ответить 
Unconnected
сообщение 14.06.2010 18:07
Сообщение #8


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


У меня Windows 7 Home Basic. Пробовал запускать свой проект на виртуалке с XP - при нажатии кнопки Начать выпрыгивает ошибка Windows (Отправить отчёт\не отправлять). Если открываю твой проект, то "Unable to load project C:\Users\Unconnected\Desktop\Spy Dir\Project1.dproj".

А ReadDirectoryChangeW возвращает False и выдаёт Error "Параметр задан неверно". На Севене я не под администратором сижу, запись в корень диска C: запрещена, например.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.06.2010 18:14
Сообщение #9


Гость






Цитата
На Севене я не под администратором сижу, запись в корень диска C: запрещена, например.
Так я и под XP не под администратором, если что, запись в корень диска у меня тоже запрещена, я ж в корень-то и не пишу, я в подпапку, а туда уже можно... Сейчас гляну, что там может вызывать такую ошибку.
 К началу страницы 
+ Ответить 
volvo
сообщение 14.06.2010 18:59
Сообщение #10


Гость






Ты будешь смеяться, но:
Прикрепленное изображение

(Win7 Ultimate, запускал под НЕадминским аккаунтом).
 К началу страницы 
+ Ответить 
Unconnected
сообщение 14.06.2010 23:18
Сообщение #11


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Фигня какая-то.. И как я его уже только не пробовал) Volvo, а ты не мог бы ради интереса приложить скомпилированный exe, который у тебя работает? (да-да, я понимаю риск... smile.gif ))


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 14.06.2010 23:47
Сообщение #12


Гость






Ну, понимаешь - тогда пробуй:


Прикрепленные файлы
Прикрепленный файл  Project1.zip ( 260.11 килобайт ) Кол-во скачиваний: 135
 К началу страницы 
+ Ответить 
Unconnected
сообщение 14.06.2010 23:53
Сообщение #13


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Создал C:\1\555_21.png - работает.. Наверное, руки не оттуда мои, попробую со средой поколдовать. Спасибо за код smile.gif


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Unconnected
сообщение 15.06.2010 23:39
Сообщение #14


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Поставил D2009, скомпилировал начальные исходники volvo - такая же фигня, только почему-то когда в CheckPath пишешь путь к папке - говорит про неверный параметр, а когда к файлу - не говорит ничего, но и не следит. Ладно, чёрт с ним, наверное, у меня в системе что-то наворочено. А можно тогда просто запретить переименование файла? Мне кажется, в сторону SetWindowsHookEx смотреть надо, там вроде любое действие отловить можно.

Добавлено через 17 мин.
И сам нагуглил-додумался smile.gif Достаточно открыть файл в потоке, TFileStream.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 10.07.2025 21:07
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"