![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ReadDirectoryChangesw
Vintik © (2005-07-28 07:55:00)Всем привет.Мастера помогите погибаю.Несколько дней не могу разобраться с ReadDirectoryChangesW.Первый вопрос такой каким типом должны быть объявленые в структуре параметры.2 как извлеч имя файла который был изменен в каталоге.Здесь на сайте есть пример,но не описаны папаметры.Если не затруднит приведите кто-нибуть полный пример буду очень пирзнателей.Спасибо
Vintik (2005-07-29 10:49:00) [1]Всем спасибо(особенно kblc очень сильно помог) разобрался просто в стуктуре надо было FileName объявить как строковый массив.И все пошло как по маслу.
vintik (2005-07-29 07:49:00) [2]В структуре FileName:PWodeChar
в процедуре TMonDirThread.Execute;
FileName:PwideChar;
При написании FileName:=PFileNotifyInformation(Ptr).FileName
запускаю программу и поток,обращаюсь к папке мониторинга при создании,удалении .... файла программа вылетает с сообщением
............ошибки в моем модуле по адресу 004044EF.Read of address 04350422.
А если заменить на При написании FileName:=IntToStr(PFileNotifyInformation(Ptr).PFileNotifyInformation(Ptr).FileNameLength div 2+1);все в порядке выводит длину файла вызвавшего изменение.?????????????????
Alexander Panov (2005-07-28 14:27:00) [3]procedure WorkThread(LV: TMemo);stdcall;
//(c) - Исходник взят(и адаптирован к себе) с
// http://delphiworld.narod.ru/base/read_directory_changes_w.html
//
var
HDir : THandle;
lpBuf : Pointer;
Ptr : Pointer;
cbReturn : Cardinal;
FileName : PWideChar;
sTime : _SYSTEMTIME;
Index: Integer;
begin
HDir := CreateFile (
'x:\temp',
GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
0);
if HDir = INVALID_HANDLE_VALUE then
begin
MessageBox(0,PChar(SysErrorMessage(GetLastError)),'Error',MB_OK);
Exit;
end;
GetMem(lpBuf,BUF_SIZE);
repeat
ZeroMemory(lpBuf,BUF_SIZE);
if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,
FILE_NOTIFY_CHANGE_LAST_WRITE+FILE_NOTIFY_CHANGE_FILE_NAME,@cbReturn,nil,nil) then
begin
MessageBox(0,PChar(SysErrorMessage(GetLastError)),'Error',MB_OK);
Break;
end;
Ptr:=lpBuf;
repeat
GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
PFileNotifyInformation(Ptr).FileNameLength div 2+1);
Index := LV.Lines.Add('X:\'+FileName);
FreeMem(FileName);
case PFileNotifyInformation(Ptr).Action of
FILE_ACTION_ADDED : LV.Lines[Index]:= LV.Lines[Index]+('Файл был создан');
FILE_ACTION_REMOVED : LV.Lines[Index]:= LV.Lines[Index]+('Файл был удален');
FILE_ACTION_MODIFIED : LV.Lines[Index]:= LV.Lines[Index]+('Файл был изменен');
FILE_ACTION_RENAMED_OLD_NAME :
LV.Lines[Index]:= LV.Lines[Index]+('Файл был переименован и в имени файла - предыдущее имя');
FILE_ACTION_RENAMED_NEW_NAME :
LV.Lines[Index]:= LV.Lines[Index]+('новое имя после переименования');
else LV.Lines[Index]:= LV.Lines[Index]+('Произошло что-то странное');
end;
// Время, когда произошло событие
GetLocalTime(sTime);
with sTime do
LV.Lines[Index]:= LV.Lines[Index]+(Format(' %.2d:%.2d:%.2d',[wHour,wMinute,wSecond])); // 13:54:20
// Если эта запись не последняя (NextEntryOffset < > 0), то...
if PFileNotifyInformation(Ptr).NextEntryOffset=0
then Break
else begin
// ... добавляем строку в примечания (если интересно посмотреть смещение)
LV.Lines[Index]:= LV.Lines[Index]+(' Offset : '+
IntToStr(PFileNotifyInformation(Ptr).NextEntryOffset));
//Передвигаем указатель на NextEntryOffset байт вперед
Inc(Cardinal(Ptr),PFileNotifyInformation(Ptr).NextEntryOffset);
// Теперь Ptr указывает на следующую запись
end;
// Передвигать надо именно Ptr, а не lpBuf
until false;
until false;
// Очищаем память
FreeMem(lpBuf);
end;
kblc (2005-07-28 14:03:00) [4]Попробуй
FileName: string;заменить наFileName: WideString;, а после не использовать ф-июlstrcpynW, а вместо этого написатьFileName:=PFileNotifyInformation(Ptr).FileName;Что у тебя получилось?
Vinkti (2005-07-28 13:36:00) [5]С основным кодом все в порядке разбрался,но при попытке вывести имя файла вызвавшего изменение в Memo поле ни чего не выводится, такое ощущение создается,что в FileName ни чего нет.
GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
PFileNotifyInformation(Ptr).FileNameLength div 2+1);
Помогите.
(2005-07-28 10:39:00) [6]Удалено модератором
Vintik (2005-07-28 08:55:00) [7]Спасибо надеюсь что теперь получится.
kblc (2005-07-28 08:47:00) [8]а потом, уже после того что я тебе написал,
type
...
PFileNotifyInformation = ^_FILE_NOTIFY_INFORMATION
...
kblc (2005-07-28 08:45:00) [9]Объяви у себя:
type
...
_FILE_NOTIFY_INFORMATION = record
NextEntryOffset: DWORD;
Action: DWORD;
FileNameLength: DWORD;
FileName: WIDECHAR;
end;
...
Кажется так... сейчас не вспомню...
Vintik (2005-07-28 08:44:00) [10]Как это применить в Delphi.На примере приведенного тобой выше?
Я пробовал но что-то не очень вышло.
kblc (2005-07-28 08:40:00) [11]typedef struct _FILE_NOTIFY_INFORMATION {
DWORD NextEntryOffset;
DWORD Action;
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
Vintik (2005-07-28 08:34:00) [12]kblc © спасибо.Еще один вопросик опиши пожалуйтва структуру которую ты используешь в этом коде.В ней у меня как раз и вся проблема не могу понять какого типа в ней поля должны быть(PFileNotifyInformation и есть имя структуры.Да?)
kblc (2005-07-28 08:31:00) [13]Вот те кусок кода - разбирайся ;)
.......
hDir := CreateFile ('C:\2',GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir = INVALID_HANDLE_VALUE
then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end;
GetMem(lpBuf,BUF_SIZE);
repeat
ZeroMemory(lpBuf,BUF_SIZE);
if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil)
then Break;
Ptr:=lpBuf;
repeat
GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
PFileNotifyInformation(Ptr).FileNameLength div 2+1);
FreeMem(FileName);
case PFileNotifyInformation(Ptr).Action of
FILE_ACTION_ADDED : Файл был создан;
FILE_ACTION_REMOVED : Файл был удален;
FILE_ACTION_MODIFIED : Файл был изменен;
until false;
until false;
FreeMem(lpBuf);
.....
Vintik (2005-07-28 08:31:00) [14]Подскажите какой тип должен иметь поле Action(действие)в структуре.И как можно определить тип произошедших действий(создание\удаление\.....?
Vintik (2005-07-28 08:14:00) [15]Мне бы примерчик.Это я уже читал.А реализовать не получается.
kblc (2005-07-28 08:01:00) [16]Тебе сюда: там ты много что найдёшь... http://search.microsoft.com/search/results.aspx?qu=ReadDirectoryChangesW&View=msdn&st=b&c=4&s=1&swc=4