在
在世寻欢
Unregistered / Unconfirmed
GUEST, unregistred user!
如题,有时一次文件修改会被读取两次,还有就是*.xls文件打开和关闭时都会得到被修改的通知,不知何故。监控线程代码如下。
unit WatchThread;
interface
uses
Classes,SysUtils,StdCtrls,Windows,Dialogs;
type
TWatchThread = class(TThread)
private
FIndex:BYTE;
FPathAnsiChar;
FHandle:THandle;
bKickHidden:Boolean;
IgnoreFileList:TStrings;
lpBufferointer;
pszTrack:string;
protected
procedure BeginWatch();
procedure Execute; override;
public
bContinue:Boolean;
constructor Create(CreateSuspended:Boolean;WatchPathAnsiChar;AIndex:BYTE;bIgnoreHidden:Boolean;IgnoreFiles:TStrings);
destructor Destroy;override;
end;
implementation
uses
Main;
procedure TWatchThread.BeginWatch;
var
dwRetBytes: DWORD;
pszFileName:string;
pszDir:string;
pszTemp:string;
begin
pszDir:=StrPas(FPath);
if pszDir[Length(pszDir)]<>'/' then
pszDir:=pszDir+'/';
GetMem(lpBuffer,nSize);
ZeroMemory(lpBuffer,nSize);
FHandle := CreateFile(FPath,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
0);
dwRetBytes:=0;
while ReadDirectoryChanges(FHandle,lpBuffer,nSize,True,
FILE_NOTIFY_CHANGE_LAST_WRITE,
@dwRetBytes,nil,nil) do
begin
if not Flag then Break;
if dwRetBytes=0 then
begin
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if PFileNotifyInformation(lpBuffer)^.Action<>FILE_ACTION_MODIFIED then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszFileName:=pszDir+WideCharToString(@(PFileNotifyInformation(lpBuffer)^.FileName[0]));
if Pos('DESKTOP.INI',UpperCase(pszFileName))>0 then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if FileIsHidden(pszFileName) and bkickHidden then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if IgnoreFileList.IndexOf(pszFileName)>-1 then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszTemp:=FormatDateTime('c": "',Now)+Format('文件[%s]内容被修改',[pszFileName]);
if SameText(UpperCase(pszTrack),UpperCase(pszTemp)) then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszTrack:=pszTemp;
AppendTrackList(pszTrack,FIndex);
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
end;
end;
constructor TWatchThread.Create(CreateSuspended: Boolean;
WatchPath: PAnsiChar; AIndex:BYTE;bIgnoreHidden:Boolean;IgnoreFiles:TStrings);
begin
inherited Create(CreateSuspended);
FPath:=WatchPath;
FIndex:=AIndex;
FreeOnTerminate:=True;
bKickHidden:=bIgnoreHidden;
IgnoreFileList:=TStringList.Create;
if IgnoreFiles.Count>0 then
IgnoreFileList.Assign(IgnoreFiles);
end;
destructor TWatchThread.Destroy;
begin
FreeMem(lpBuffer,nSize);
inherited;
end;
procedure TWatchThread.Execute;
begin
inherited;
BeginWatch;
end;
end.
代码:
interface
uses
Classes,SysUtils,StdCtrls,Windows,Dialogs;
type
TWatchThread = class(TThread)
private
FIndex:BYTE;
FPathAnsiChar;
FHandle:THandle;
bKickHidden:Boolean;
IgnoreFileList:TStrings;
lpBufferointer;
pszTrack:string;
protected
procedure BeginWatch();
procedure Execute; override;
public
bContinue:Boolean;
constructor Create(CreateSuspended:Boolean;WatchPathAnsiChar;AIndex:BYTE;bIgnoreHidden:Boolean;IgnoreFiles:TStrings);
destructor Destroy;override;
end;
implementation
uses
Main;
procedure TWatchThread.BeginWatch;
var
dwRetBytes: DWORD;
pszFileName:string;
pszDir:string;
pszTemp:string;
begin
pszDir:=StrPas(FPath);
if pszDir[Length(pszDir)]<>'/' then
pszDir:=pszDir+'/';
GetMem(lpBuffer,nSize);
ZeroMemory(lpBuffer,nSize);
FHandle := CreateFile(FPath,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
0);
dwRetBytes:=0;
while ReadDirectoryChanges(FHandle,lpBuffer,nSize,True,
FILE_NOTIFY_CHANGE_LAST_WRITE,
@dwRetBytes,nil,nil) do
begin
if not Flag then Break;
if dwRetBytes=0 then
begin
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if PFileNotifyInformation(lpBuffer)^.Action<>FILE_ACTION_MODIFIED then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszFileName:=pszDir+WideCharToString(@(PFileNotifyInformation(lpBuffer)^.FileName[0]));
if Pos('DESKTOP.INI',UpperCase(pszFileName))>0 then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if FileIsHidden(pszFileName) and bkickHidden then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
if IgnoreFileList.IndexOf(pszFileName)>-1 then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszTemp:=FormatDateTime('c": "',Now)+Format('文件[%s]内容被修改',[pszFileName]);
if SameText(UpperCase(pszTrack),UpperCase(pszTemp)) then
begin
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
Continue;
end;
pszTrack:=pszTemp;
AppendTrackList(pszTrack,FIndex);
dwRetBytes:=0;
ZeroMemory(lpBuffer,nSize);
end;
end;
constructor TWatchThread.Create(CreateSuspended: Boolean;
WatchPath: PAnsiChar; AIndex:BYTE;bIgnoreHidden:Boolean;IgnoreFiles:TStrings);
begin
inherited Create(CreateSuspended);
FPath:=WatchPath;
FIndex:=AIndex;
FreeOnTerminate:=True;
bKickHidden:=bIgnoreHidden;
IgnoreFileList:=TStringList.Create;
if IgnoreFiles.Count>0 then
IgnoreFileList.Assign(IgnoreFiles);
end;
destructor TWatchThread.Destroy;
begin
FreeMem(lpBuffer,nSize);
inherited;
end;
procedure TWatchThread.Execute;
begin
inherited;
BeginWatch;
end;
end.