掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
深い階層のファイルの変更を検知するには? (ID:34418)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
真琴:「ハルコさん、階層が深いSubフォルダのファイル変更もこれで監視できるの?」 春子:「そぅよ、EditにフォルダPATHを入れて、Startボタン押して確かめてみたら?」 真琴:「あっ、そのSubフォルダのファイル書き換えや新規作成、コピーなんかでも、そのファイル名が表示されるね」 春子:「でしょ? もちろん深いSubフォルダ名の変更、作成の検知もOK」 真琴:「なるほど、スレッドを使って監視してるのね? でも、ハルコさん…」 春子:「ん? なに?」 真琴:「けっこう面倒よね?この方法も^^;、API一発で分かるって方法とかない?^^;;」 春子:「世の中そんな甘くないって」 type PFileNotifyInformation = ^TFileNotifyInformation; TFileNotifyInformation = record NextEntryOffset: DWORD; Action: DWORD; FileNameLength: DWORD; FileName: array[0..0] of WideChar; end; const FILE_LIST_DIRECTORY = $0001; ActionDsp: array[FILE_ACTION_ADDED..FILE_ACTION_RENAMED_NEW_NAME] of string = ('ADDED %s','DELETED %s','MODIFIED %s','RENAME_Old %s','RENAME_New %s'); var NotifyBuf: array[0..$1000] of Byte; NotifyFilter: DWORD; hDirectory: THandle; hCompletionPort: THandle; Overlapped: TOverlapped; rwBytes: DWORD; type TWatchThread = class(TThread) private procedure ShowInformation; public procedure Execute; override; end; var WatchThread := TWatchThread; procedure TWatchThread.ShowInformation; var pFNI: PFileNotifyInformation; Offset: Integer; begin pFNI := @NotifyBuf[0]; repeat Offset := pFNI^.NextEntryOffset; Form1.ListBox1.Items.Add(Format(ActionDsp[pFNI^.Action], [WideCharLenToString(@(pFNI^.FileName), pFNI^.FileNameLength)])); inc(PChar(pFNI), Offset); until Offset = 0; end; procedure TWatchThread.Execute; var CompletionKey: DWORD; lpOverlapped: POverlapped; begin while (not Terminated)and(not Application.Terminated) do begin lpOverlapped := @Overlapped; GetQueuedCompletionStatus(hCompletionPort, rwBytes, CompletionKey, lpOverlapped, INFINITE); if CompletionKey <> 0 then begin Synchronize(ShowInformation); ZeroMemory(@NotifyBuf, SizeOf(NotifyBuf)); ReadDirectoryChanges(hDirectory, @NotifyBuf, SizeOf(NotifyBuf), True, NotifyFilter, @rwBytes, @Overlapped, nil); end end; end; procedure TForm1.StartButtonClick(Sender: TObject); begin if Assigned(WatchThread)and(not WatchThread.Suspended) then exit; ListBox1.Clear; hDirectory := CreateFile(PChar(EditPath.Text), FILE_LIST_DIRECTORY, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0); if hDirectory = INVALID_HANDLE_VALUE then begin hDirectory := 0; ShowMessage(SysErrorMessage(GetLastError)); exit; end; NotifyFilter := FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_CREATION; hCompletionPort := CreateIoCompletionPort(hDirectory, 0, DWORD(Pointer(Self)), 0); ZeroMemory(@NotifyBuf, SizeOf(NotifyBuf)); if not ReadDirectoryChanges(hDirectory, @NotifyBuf, SizeOf(NotifyBuf), True, NotifyFilter, @rwBytes, @Overlapped, nil) then begin CloseHandle(hDirectory); CloseHandle(hCompletionPort); hDirectory := 0; hCompletionPort := 0; ShowMessage(SysErrorMessage(GetLastError)); exit; end; EditPath.Enabled := False; WatchThread := TWatchThread.Create(True); WatchThread.FreeOnTerminate := False; WatchThread.Resume; end; procedure TForm1.StopButtonClick(Sender: TObject); begin if hCompletionPort = 0 then exit; PostQueuedCompletionStatus(hCompletionPort, 0, 0, nil); if Assigned(WatchThread) then begin WatchThread.Terminate; WatchThread.WaitFor; WatchThread.Free; WatchThread := nil; end; CloseHandle(hDirectory); hDirectory := 0; CloseHandle(hCompletionPort); hCompletionPort := 0; EditPath.Enabled := True; end; procedure TForm1.FormDestroy(Sender: TObject); begin StopButton.Click; end; procedure TForm1.FormCreate(Sender: TObject); begin ListBox1.Font.Name := 'MS ゴシック'; hCompletionPort := 0; hDirectory := 0; ZeroMemory(@Overlapped, SizeOf(Overlapped)); end; 春子:「ところで、マコト、どう? 久しぶりの中学生活はもう慣れたかな?」 真琴:「それがまだ…、忘れてたコトも多いから友達と話をあわせるのがもう大変」 春子:「ま、4年ぶりだからね」 真琴:「でも、ハルコさん、どうしてアタシの話をあっさり信じてくれたの?」 春子:「そっかぁ、マコトは憶えてないんだね、4年前に戻ったワケを」 真琴:「えっ、ワケって、ハルコさんはそれを知ってるの?」 春子:「モチロン…、ジツはネ、マコトはまた、時の迷子になっちゃったのよ」 真琴:「時の迷子? それってどういうコト? よく分からないけど、ナンで?」 春子:「ナンでって…理由はアタシの方が聞きたいよ、もう、めちゃアセッタんだから」 真琴:「だって、そんな記憶ゼンゼンないもん、それでどうなったの?」 春子:「1回目の時はまだアタシの能力があって助けられたけど、今回はもうダメかと」 真琴:「でも、またハルコさんが助けてくれたの? えっ、それじゃ、もしかして…」 春子:「ホントに何も憶えてない? どうしても元に戻る出口が見つからず、やっと見つけたのが4年前の出口だったってコトを」 真琴:「憶えてない…」 春子:「もう死ぬ覚悟で、最後の力を振り絞って助けたんだから、感謝してよネ」 真琴:「それがホントならモチロン大感謝だけど…、もしかしてまた冗談話とか^^;」 春子:「こうして冗談話が聞けるのも助かったからでしょ? …あっ、予約のお客様が到着したのかな?」 真琴:「え〜? やっぱり冗談? それともホント? ねぇどっちなのぉ?」
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.