全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2863
推到 Plurk!
推到 Facebook!

關於ReadDirectoryChangesW API的使用方式

答題得分者是:小傑克
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-05-22 12:35:02 IP:220.130.xxx.xxx 訂閱
這幾天一直在研究這方面的東西,但實作上真的卡很多東西

網路上的範例在我看起來,說實在的很多東西看不懂,在此提出我的疑點

希望前輩們能多多指教

根據 ReadDirectoryChangesW 定義如下
BOOL ReadDirectoryChangesW(
HANDLE hDirectory, \\監控路徑
LPVOID lpBuffer, \\緩衝區初始設置,雖然知道,但要怎麼設,是否有什麼技巧?
DWORD nBufferLength, \\緩衝區長度設置
BOOL bWatchSubtree, \\是否監控子目錄
DWORD dwNotifyFilter, \\設定要過濾的條件
LPDWORD lpBytesReturned, \\請前輩指教
LPOVERLAPPED lpOverlapped, \\請前輩指教
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine \\請前輩指教
);

而ReadDiectoryChangesW的 hDirectory 不能直接指定目錄嗎?

為什麼網路上會有範例說利用CreateFile來取得 hDirectory的返回值?

以上就是我對這個函數的質疑部份~

希望有空的前輩們幫忙回答一下~

基本功不夠,我會再努力精進的,先謝謝各位前輩了~
------
尋找對的人,對的方法,對的態度跟對的環境
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-05-22 13:25:44 IP:59.112.xxx.xxx 訂閱
看的出來想完全只靠MSDN 寫出這個sample 不容易, 可能要試很久 , 還好總是有前輩已經花時間去做
實際上程式寫法參考這篇
http://www.delphipages.com/threads/thread.cfm?ID=23571&G=23547


定義方面可以參考 http://msdn.microsoft.com/en-us/library/aa365465(VS.85).aspx

至於路徑說明如下
hDirectory
[in]
A handle to the directory to be monitored. This directory must be opened with the FILE_LIST_DIRECTORY access right.

如何opened with the FILE_LIST_DIRECTORY access right 則要看另外兩篇
http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

參數
dwDesiredAccess [in]
The requested access to the file or device, which can be summarized as read, write, both or neither (zero).
The most commonly used values are GENERIC_READ, GENERIC_WRITE, or both (GENERIC_READ | GENERIC_WRITE). For more information, see File Security and Access Rights.

而這個參數的內容要參考 http://msdn.microsoft.com/en-us/library/aa364399(VS.85).aspx

要用windows api 本來就要依照api的定義, 既然規定directory handle 要用 File access right 中參數FILE_LIST_DIRECTORY 取得, 當然就要這樣繞一下 希望這些資料有幫到你
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-05-22 13:26:39, 註解 無‧
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-05-22 13:46:40 IP:220.130.xxx.xxx 訂閱
真厲害耶  我搜尋好幾天的文章

沒想到小傑克前輩一下就點出我想要的東西了

真是感謝,繼續啃英文.......

謝謝您喔^^~
------
尋找對的人,對的方法,對的態度跟對的環境
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-05-25 15:09:16 IP:220.130.xxx.xxx 訂閱
這兩天研究該程式的結果,發現有幾個問題點還蠻怪的
可能我對這位作者的寫法有些地方產生很多疑問吧
我想說列舉一下,希望有經驗的前輩們能指導一下
一直麻煩前輩們幫忙解答,真是謝謝您們了,尤其是小傑克前輩
問題點如下:
1、CreateFile
[code delphi]
FDirectoryHandle := CreateFile(PChar(edRule.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);
//----------------------------------------------------------------------------
FDirectoryHandle := CreateFile(PChar(edRule.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,nil);
[/code]
當我設最後一個參數nil時,則在comple的時候,就過不了了,會發生型態錯誤

[DCC Error] frmWatch.pas(135): E2010 Incompatible types: 'Cardinal' and 'Pointer'

而我去參考help的時候,它說這個欄位的值可以為null

那這邊的0代表的意思是等於null的意思嗎?
------
尋找對的人,對的方法,對的態度跟對的環境
編輯記錄
terrygobb 重新編輯於 2009-05-25 15:10:38, 註解 無‧
terrygobb 重新編輯於 2009-05-25 15:10:59, 註解 無‧
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-05-25 15:12:10 IP:220.130.xxx.xxx 訂閱
2、程式碼如下

[code delphi]
FCompletionPort := CreateIoCompletionPort(FDirectoryHandle, 0, Longint(pointer(self)), 0);
ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer));
//為什麼要在記憶體空間裡面未填入值的空間都寫入0呢?用意是什麼呢?
FBytesWritten := 0;
[/code]


2.1
其中Longint(pointer(self))這段程式碼的轉型不太了解,我知道self是代表目前的Form
我有透過ShowMessage(IntToStr(Longint(pointer(self))))來看到底轉出什麼東西
但這樣的結果反而是一串整數,是代表一個位置嗎?
------
尋找對的人,對的方法,對的態度跟對的環境
編輯記錄
terrygobb 重新編輯於 2009-05-25 15:12:41, 註解 無‧
terrygobb 重新編輯於 2009-05-25 15:13:23, 註解 無‧
terrygobb 重新編輯於 2009-05-25 15:13:48, 註解 無‧
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-05-25 15:16:52 IP:220.130.xxx.xxx 訂閱
3. ZeroMemory的問題

[code delphi]
procedure TWaitThread.Execute;
var
....
begin
while not Terminated do
begin
GetQueuedCompletionStatus( FForm.FCompletionPort, numBytes, CompletionKey,
FForm.FPOverlapped, INFINITE);
if CompletionKey <> 0 then
begin
Synchronize(HandleEvent);
with FForm do
begin
FBytesWritten := 0;
ZeroMemory(@FNotificationBuffer, SizeOf(FNotificationBuffer));
//為什麼在這邊又要在做一次ZeroMemory呢@@?
ReadDirectoryChangesW(FDirectoryHandle, @FNotificationBuffer, SizeOf(FNotificationBuffer),
true, FNotifyFilter, @FBytesWritten, @FOverlapped, nil);
end;
end

end;
end;

[/code]
------
尋找對的人,對的方法,對的態度跟對的環境
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-05-25 22:05:46 IP:61.217.xxx.xxx 訂閱
你一次問了好幾個...這我也沒實際寫過, 沒辦法我只好去 DelphiPage 再看了一下整個sample , 有可能講的不對,大家交流一下
1. null是傳 0 沒錯, 因為他參數型態是 handle = type LongWord , 有些function 回傳 HWND會用0 或 -1 表示null 或錯誤 , 正常時會是一個常整數, 而 NIL 是 null Pointer , Pointer型別用的
2. CreateIoCompletionPort 第三個參數, 根據http://msdn.microsoft.com/en-us/library/aa363862(VS.85).aspx 的說明, 是使用者自定的一個變數,這個變數CompletionKey 是取回資料的時候識別用的, 詳細內容還有和GetQueuedCompletionStatus , PostQueuedCompletionStatus的關聯 在msdn的remark 段落有說明
3. 至於ZeroMemory .....因為每次用ReadDirectoryChangesW 之前都要先初始化 FNotificationBuffer , 他 thread execute 裡面是用 while not Terminated do 沒按下中斷紐之前會一直loop的
------
額有朝天骨,眼中有靈光
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-05-26 23:20:09 IP:61.227.xxx.xxx 訂閱
不好意思,小傑克前輩

這麼晚才回您,因為這幾天ktop好像不怎麼穩定

有時候會沒辦法上

可能是相關人員在做維修或者發生什麼事也不一定

以致於這麼晚才回您

謝謝您的答覆,這幾個禮拜以來一直麻煩您了

改天有機會見面的話,再請你吃個飯跟你說聲謝謝

關於您說的這幾個解答,我會在try的,因為我寫的程式跑出來的結果並不是我要的

thread並沒有辦法像loop一樣重覆執行,我想應該是我那個地方寫錯了

目前還在查找bug當中,還是那句話,謝謝您的用心,感謝~^^
------
尋找對的人,對的方法,對的態度跟對的環境
小傑克
資深會員


發表:5
回覆:209
積分:357
註冊:2009-02-16

發送簡訊給我
#9 引用回覆 回覆 發表時間:2009-05-27 04:25:37 IP:61.217.xxx.xxx 訂閱
大家交流心得,別這麼客氣
試試這個
http://delphi.ktop.com.tw/board.php?cid=32&fid=911&tid=98471

我拿那個sample 改的, 只多加兩三行處理event 比對 , 你可以直接監控整個硬碟, 檔案跑到哪邊去都知道

我的比對法,是用最後一個remove event 和下一個add event 比對, 當一次移動超過一個以上的檔案時, 不一定會全部抓到, 因為file system 有同步的問題, 不是先進先出的, 所以還可以再改進 , 以一次移動為單位, 將全部 remove 檔都寫到 list 裡面, Add 的時候比對才不會少 , 如果要很完整的功能 ,要考慮的東西還蠻多的
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-05-27 04:42:39, 註解 增加說明‧
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-05-27 11:50:07 IP:220.130.xxx.xxx 訂閱
對阿,要考慮的東西真的還蠻多的

謝謝您寫這個sample給我參考

我會好好的研讀的,謝謝您~
------
尋找對的人,對的方法,對的態度跟對的環境
terrygobb
一般會員


發表:5
回覆:22
積分:5
註冊:2009-04-27

發送簡訊給我
#11 引用回覆 回覆 發表時間:2009-05-27 14:26:44 IP:220.130.xxx.xxx 訂閱
Dear 小傑克前輩:

剛在研讀您的sample的時候,發現的原始程式碼

希望對大家有幫助,我去用功了,呵~再跟您說聲謝謝啦

謝謝您的提醒,我太粗心了

每天都有新的進度,雖然一直卡住,自己也很難過,但過程咩~

我會加油滴~

祝大家端午節快樂^^~

網址如下:
http://www.4shared.com/file/108058889/42333ebf/dirmon.html

------
尋找對的人,對的方法,對的態度跟對的環境
編輯記錄
terrygobb 重新編輯於 2009-05-27 16:32:00, 註解 無‧
系統時間:2024-03-28 21:43:45
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!