Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  05:53[Войти] | [Зарегистрироваться]
Ответ на вопрос № 50262

18-03-2007 06:45
помогите....

вот код для отлова изменений в фс

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,wfsU, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    CheckBox6: TCheckBox;
    CheckBox7: TCheckBox;
    CheckBox8: TCheckBox;
    CheckBox9: TCheckBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure MyInfoCallBack(pInfo: TInfoCallBack);
  const
    Action: array[1..3] of String = ('Создание: %s', 'Удаление: %s', 'Изменение: %s');
  begin
    case pInfo.FAction of
      FILE_ACTION_RENAMED_NEW_NAME: Form1.Memo1.Lines.Add(Format('Переименование: %s в %s',
          [pInfo.FDrive+pInfo.FOldFileName,pInfo.FDrive+pInfo.FNewFileName]));
    else
      if pInfo.FAction<FILE_ACTION_RENAMED_OLD_NAME then
        Form1.Memo1.Lines.Add(Format(Action[pInfo.Faction], [pInfo.FDrive+pInfo.FNewFileName]));
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Flags:Cardinal;
begin
{
FILE_NOTIFY_CHANGE_FILE_NAME        = $00000001;//изменение имени файла
FILE_NOTIFY_CHANGE_DIR_NAME        = $00000002;//изм. имени папки
FILE_NOTIFY_CHANGE_ATTRIBUTES      = $00000004;//атрибутов файла
FILE_NOTIFY_CHANGE_SIZE            = $00000008;//размера
FILE_NOTIFY_CHANGE_LAST_WRITE      = $00000010;//последней записи
FILE_NOTIFY_CHANGE_LAST_ACCESS      = $00000020;//последнего доступа
FILE_NOTIFY_CHANGE_CREATION        = $00000040;//создания
FILE_NOTIFY_CHANGE_SECURITY        = $00000100;//прав доступа
}

Flags:=0;
if CheckBox2.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_FILE_NAME;
if CheckBox3.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_DIR_NAME;
if CheckBox4.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_ATTRIBUTES;
if CheckBox5.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_SIZE;
if CheckBox6.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_LAST_WRITE;
if CheckBox7.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_LAST_ACCESS;
if CheckBox8.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_CREATION;
if CheckBox9.Checked then Flags:=Flags or FILE_NOTIFY_CHANGE_SECURITY;
                                                                                                                                                                                                                                                                            //включая подкаталоги
StartWatch(Edit1.Text, Flags, CheckBox1.Checked, @MyInfoCallBack);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
StopWatch;
end;

end.

вот управляющий юнит

unit wfsU;

interface

type
// Структура с информацией об изменении в файловой системе (передается в callback процедуру)

  PInfoCallBack = ^TInfoCallBack;
  TInfoCallBack = record
    FAction      : Integer; // тип изменения (константы FILE_ACTION_XXX)
    FDrive      : string// диск, на котором было изменение
    FOldFileName : string// имя файла до переименования
    FNewFileName : string// имя файла после переименования
  end;

  // callback процедура, вызываемая при изменении в файловой системе
  TWatchFileSystemCallBack = procedure (pInfo: TInfoCallBack);

{ Запуск мониторинга файловой системы
  Праметры:
  pName    - имя папки для мониторинга
  pFilter  - комбинация констант FILE_NOTIFY_XXX
  pSubTree - мониторить ли все подпапки заданной папки
  pInfoCallBack - адрес callback процедуры, вызываемой при изменении в файловой системе}

procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallBack: TWatchFileSystemCallBack);
// Остановка мониторинга
procedure StopWatch;

implementation

uses
  Classes, Windows, SysUtils;

const
  FILE_LIST_DIRECTORY  = $0001;

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

  WFSError = class(Exception);

  TWFS = class(TThread)
  private
    FName          : string;
    FFilter        : Cardinal;
    FSubTree        : boolean;
    FInfoCallBack  : TWatchFileSystemCallBack;
    FWatchHandle    : THandle;
    FWatchBuf      : array[0..4096] of Byte;
    FOverLapp      : TOverlapped;
    FPOverLapp      : POverlapped;
    FBytesWritte    : DWORD;
    FCompletionPort : THandle;
    FNumBytes      : Cardinal;
    FOldFileName    : string;
    function CreateDirHandle(aDir: string): THandle;
    procedure WatchEvent;
    procedure HandleEvent;
  protected
    procedure Execute; override;
  public
    constructor Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallBack: TWatchFileSystemCallBack);
    destructor Destroy; override;
  end;

var
  WFS : TWFS;

procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallBack: TWatchFileSystemCallBack);
begin
WFS:=TWFS.Create(pName, pFilter, pSubTree, pInfoCallBack);
end;

procedure StopWatch;
var
  Temp : TWFS;
begin
  if Assigned(WFS) then
  begin
  PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil);
  Temp := WFS;
  WFS:=nil;
  Temp.Terminate;
  end;
end;

constructor TWFS.Create(pName: string; pFilter: cardinal;
  pSubTree: boolean; pInfoCallBack: TWatchFileSystemCallBack);
begin
  inherited Create(True);
  FreeOnTerminate:=True;
  FName:=IncludeTrailingBackslash(pName);
  FFilter:=pFilter;
  FSubTree:=pSubTree;
  FOldFileName:=EmptyStr;
  ZeroMemory(@FOverLapp, SizeOf(TOverLapped));
  FPOverLapp:=@FOverLapp;
  ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
  FInfoCallBack:=pInfoCallBack;
  Resume
end;

destructor TWFS.Destroy;
begin
  PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
  CloseHandle(FWatchHandle);
  FWatchHandle:=0;
  CloseHandle(FCompletionPort);
  FCompletionPort:=0;
  inherited Destroy;
end;

function TWFS.CreateDirHandle(aDir: string): THandle;
begin
Result:=CreateFile(PChar(aDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ+FILE_SHARE_DELETE+FILE_SHARE_WRITE,
                  nil,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
end;

procedure TWFS.Execute;
begin
  FWatchHandle:=CreateDirHandle(FName);
  WatchEvent;
end;

procedure TWFS.HandleEvent;
var
  FileNotifyInfo : PFileNotifyInformation;
  InfoCallBack  : TInfoCallBack;
  Offset        : Longint;
begin
  Pointer(FileNotifyInfo) := @FWatchBuf[0];
  repeat
    Offset:=FileNotifyInfo^.NextEntryOffset;
    InfoCallBack.FAction:=FileNotifyInfo^.Action;
    InfoCallBack.FDrive:=FName;
    SetString(InfoCallBack.FNewFileName,FileNotifyInfo^.FileName,
              FileNotifyInfo^.FileNameLength );
    InfoCallBack.FNewFileName:=Trim(InfoCallBack.FNewFileName);
    case FileNotifyInfo^.Action of
      FILE_ACTION_RENAMED_OLD_NAME: FOldFileName:=Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
      FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName:=FOldFileName;
    end;
    FInfoCallBack(InfoCallBack);
    PChar(FileNotifyInfo):=PChar(FileNotifyInfo)+Offset;
  until (Offset=0) or Terminated;
end;

procedure TWFS.WatchEvent;
var
CompletionKey: Cardinal;
begin
  FCompletionPort:=CreateIoCompletionPort(FWatchHandle, 0, Longint(pointer(self)), 0);
  ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
  if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree,
    FFilter, @FBytesWritte,  @FOverLapp, 0) then
  begin
    raise WFSError.Create(SysErrorMessage(GetLastError));
    Terminate;
  end else
  begin
    while not Terminated do
    begin
      GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE);
      if CompletionKey<>0 then
      begin
        Synchronize(HandleEvent);
        ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
        FBytesWritte:=0;
        ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter,
                            @FBytesWritte, @FOverLapp, 0);
      end else Terminate;
    end
  end
end;

end.

вопрос - если добавляю несколько директорий для мониторинга как удалить потом ненужную директорию?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

22-03-2007 12:45
В коде разбираться особо было лень, так вот основное: кормите каждому потоку в качестве параметра (поскольку я создаю потоки через API, это будет "настоящий" параметр, у вас это будет "лишний" параметр конструктора) Handle Event'а. Его надо передавать в WaitForMultipleObjects одним из параметров и снимать поток, когда взведется событие напрочь. На API для этого достаточно прервать работу процедуры потока, здесь - выйти из Execute. Надо где-то хранить список соответствия каталогов и ликвидных событий. Закрывать событие можно в конце потока, у вас - в деструкторе.

20-03-2007 11:37 | Сообщение от автора вопроса
FindCloseChangeNotification - закончить и??? если я запустил 20 процессов....как выбрать то нужный из 20??? или как остановить все, но с возможностью запустить потом нужные?

19-03-2007 06:04 | Комментарий к предыдущим ответам
я вроде написал FindCloseChangeNotification

19-03-2007 05:55 | Сообщение от автора вопроса
Это все понятно, как запустить я знаю... Как нужный то остановить???

19-03-2007 05:50
FindFirstChangeNotification - начать мониторинг
FindNextChangeNotification - продолжить
FindCloseChangeNotification - закончить

http://msdn2.microsoft.com/en-us/library/aa364417.aspx

19-03-2007 03:17 | Сообщение от автора вопроса
Вопрос в другом. Вот я начал мониторин дирректории потом еще одной и т д (например 20 дирректорий ), как мне потом остановить мониторинг в ненужной более дирректории (из ранее запущенных)???

18-03-2007 15:19
»вопрос КС №50217«

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Какой месяц идет после марта?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования