如何实时监视某个文件是否被打开过

Lo 2003-07-30 04:35:10
我需要一直监视某个文件是否有被打开,如果被打开,刚触发相应的事件。。

大家帮忙.
...全文
423 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyszh 2003-08-05
  • 打赏
  • 举报
回复
呵呵,只能问问杀毒软件的编写者。
pepsi1980(磨刀老头*吾貌虽瘦,必肥天下) 说的有道理。
jackyren 2003-08-01
  • 打赏
  • 举报
回复
http://www.codeproject.com/file/directorychangewatcher.asp#xx544102xx

去看看吧,应该能够解决你的问题。所提供的例子,可以监视last access!

共同学习,因为你提出的问题,让我想到我某个一直困扰我的难题的解决思路!谢谢!
COKING 2003-08-01
  • 打赏
  • 举报
回复
看CIH的源码去!
Lo 2003-08-01
  • 打赏
  • 举报
回复
各位大侠,我想我要先说清楚,我监视的是声音文件,我只要监视它什么时候是否被打开播放了。
打开播放时并不会修改文件的,所以不会修改文件的“修改时间”。
至于用“访问时间”的话,好像在98下根本就没有这项。
hongliqiu 2003-07-31
  • 打赏
  • 举报
回复
NTFS格式的应该没有问题,可能在98下不行。
jackyren 2003-07-31
  • 打赏
  • 举报
回复
你可以使用FindFirstChangeNotification....

我暂时不能帮你写个程序实现,请参看下面的代码(微软的例子)

DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];

// Watch the C:\WINDOWS directory for file creation and
// deletion.

dwChangeHandles[0] = FindFirstChangeNotification(
"C:\\WINDOWS", // directory to watch
FALSE, // do not watch the subtree
FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

// Watch the C:\ subtree for directory creation and
// deletion.

dwChangeHandles[1] = FindFirstChangeNotification(
"C:\\", // directory to watch
TRUE, // watch the subtree
FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir. name changes

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

// Change notification is set. Now wait on both notification
// handles and refresh accordingly.

while (TRUE)
{

// Wait for notification.

dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
FALSE, INFINITE);

switch (dwWaitStatus)
{
case WAIT_OBJECT_0:

// A file was created or deleted in C:\WINDOWS.
// Refresh this directory and restart the
// change notification. RefreshDirectory is an
// application-defined function.

RefreshDirectory("C:\\WINDOWS")
if ( FindNextChangeNotification(
dwChangeHandles[0]) == FALSE )
ExitProcess(GetLastError());
break;

case WAIT_OBJECT_0 + 1:

// A directory was created or deleted in C:\.
// Refresh the directory tree and restart the
// change notification. RefreshTree is an
// application-defined function.

RefreshTree("C:\\");
if (FindNextChangeNotification(
dwChangeHandles[1]) == FALSE)
ExitProcess(GetLastError());
break;

default:
ExitProcess(GetLastError());
}
}
Alpha_Gu 2003-07-31
  • 打赏
  • 举报
回复
寫注冊表
心平至和 2003-07-31
  • 打赏
  • 举报
回复
UINT MoniterProc(PVOID pParam)
{
PMoniter Mo=(PMoniter)pParam;
BOOL Get;
char Notify[1000];
PFILE_NOTIFY_INFORMATION pInfo=(FILE_NOTIFY_INFORMATION*)Notify;
DWORD Recv;
int Len;
char Ansi[MAX_PATH];
Mo->bStop=false;
bool Ok;
while(!Mo->bStop)
{
Ok=false;
Get=ReadDirectoryChangesW(Mo->hDir,pInfo,sizeof(Notify),
true,FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_ATTRIBUTES,
&Recv,NULL,NULL);
ASSERT(Get==TRUE);
memset(Ansi,0,sizeof(Ansi));

Len=WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,pInfo->FileName,
pInfo->FileNameLength,Ansi,sizeof(Ansi),NULL,NULL);
if(Len==0)
{
DWORD re=GetLastError();
Log(CString("get the error with filename")+Ansi);
continue;
}
if(AddFile(Ansi,sizeof(Ansi)))
SendMessage(Mo->hWnd,WM_SHELL_TRAY,NEED_BACKUP,WM_LBUTTONDOWN);
}
bool test=Mo->bStop;
try
{
pFtp->Release();
}catch(...){};
return 0;
}

bool CWatchDir::StartWatch(void)
{
if(hDir!=NULL)
{
mMoniter.bStop=true;
CloseHandle(hDir);
CloseHandle(hThread);
}
hDir=CreateFile(mMoniter.Dir,FILE_LIST_DIRECTORY, FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
ASSERT(hDir!=NULL);
mMoniter.hDir=hDir;
if(hDir==INVALID_HANDLE_VALUE)
{
//(mMoniter.hWnd,WM_GET_WATCH,WATCH_ERROR,0);
return false;
}
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MoniterProc,(PVOID)&mMoniter,0,NULL);
return true;
}
这个例子应该非常满足你的要求,最好改成异步的好控制。要不最后要强制停止线程。
pepsi1980 2003-07-31
  • 打赏
  • 举报
回复
下面的Delphi的代码,太长了,要的可以给我发短信
pepsi1980 2003-07-31
  • 打赏
  • 举报
回复
用 FileAge(C:\\abc.txt) 函数可以得到指定文件的修改时间.各位BCB高人们,我在练习用win api对硬盘的监视过程中,碰到一个不知道怎么办的问题,一个MEMO一个Button我用如下代码在Button1按钮中:
if(FindFirstChangeNotification("e:\\Sxzp501\\",false,FILE_NOTIFY_CHANGE_LAST_WRITE)==INVALID_HANDLE_VALUE)
ShowMessage("Error");
else
{
if(WaitForSingleObject(FindFirstChangeNotification("e:\\Sxzp501\\",false,FILE_NOTIFY_CHANGE_LAST_WRITE),INFINITE)==WAIT_FAILED)
ShowMessage("Error");
else
Memo1->Lines->Add("Changed");
FindCloseChangeNotification(FindFirstChangeNotification("e:\\Sxzp501\\",false,FILE_NOTIFY_CHANGE_LAST_WRITE));
}
的确可以发现有文件在作存盘操作,可是我怎么知道具体是什么文件呢在作存盘操作呢?
请缎给出具体的代码。分数大的,不够再加!

另外,对注册表进行监视的API有哪些呢?请详细一些。





答:

给你找段代码吧。。

在WIN32下用DELPHI侦测目录变化,可用WIN32提供的文件改变通知API来完成。FindFirstChangeNotification, FindNextChangeNotification,FindCloseChangeNotification。
在应用程序中调用这些函数时,产生一个监控这个变化的句柄,可用WAIT函数集来等待这个变化。这样,当监控程序运行时,可以达到监控文件变化的动作。更进一步,可把此程序做成一个状态区图标(TRAY)来完成监控。

Windows在删除、复制、移动、访问文件时并不发送消息,当然截获不到。要截取这些操作过程的唯一办法就是截获API,这又需要你编写Vxd程序了,杀毒软件都是这样作的。你注意一下杀毒软件一般都带有一个vxd程序。光有vxd还不行,还需截获文件API。还有另外一个办法,就是CIH病毒采用的办法,直接跳到系统零层去操作。具体办法如下:
一、SIDT指令( 将中断描述符表寄存器IDTR--64位宽,16~47Bit存有中断描述符表IDT基地址--的内容存入指定地址单元)不是特权指令,就是说我们可以在Ring3下执行该指令,获得IDT的基地址,从而修改IDT,增加一个中断门安置我们的中断服务,一旦Ring3程序中产生此中断,VMM就会调用此中断服务程序,而此中断服务程序就运行在Ring0下了。这一点与在DOS下非常相似。

二、要实现对系统中所有文件I/O操作的实时监视,还要用到另一种关键技-FileHooking,通过挂接一个处理函数,截获所有与文件I/O操作有关的系 统调用。Windows9x使用32位保护模式可安装文件系统(IFS),由可安装文件系统管理器(IFSManager)协调对文件系统和设备的访问,它接收以Win32API函数调用形式向系统发出的文件I/O请求,再将请求转给文件系统驱动程序FSD,由它调用低级别的IOS系统实现最终访问。每个文件I/OAPI调用都有一个特定的FSD函数与之对应,IFSManager负责完成由API到FSD的参数装配工作,在完成文件I/OAPI函数参数的装配之后转相应FSD执行之前,它会调用一个称为FileSystemApiHookFunction的Hooker函数。通过安装自己的Hooker函数,就可以截获系统内所有对文件I/O的API调用,从而实现实时监控。

yesry 2003-07-31
  • 打赏
  • 举报
回复
HANDLE dwChangeHandles[2];

dwChangeHandles[0] = FindFirstChangeNotification(
"C:\\",
FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME);

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

dwChangeHandles[1] = FindFirstChangeNotification(
"C:\\",
TRUE,
FILE_NOTIFY_CHANGE_DIR_NAME);

if(dwChangeHandles[1] == INVALID_HANDLE_VALUE)
ExitProcess(GetLastError());

while (TRUE)
{
if(WaitForMultipleObjects(2, dwChangeHandles,
FALSE, INFINITE)!=WAIT_OBJECT_0)break;
ShowMessage("changed");

if(FindNextChangeNotification(dwChangeHandles[0]) == FALSE)//必不可少
break;
if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE)
break;
}
ShowMessage("end");
}
//---------------------------------------------------------------------------


可以用文件的最后修改日期比较来得到最近修改过的文件。
zihan 2003-07-31
  • 打赏
  • 举报
回复
你可以查看他的最后访问时间啊,他的文件属性里面有一个最后访问时间核最后修改时间,就可以知道他是否被修改过,如果你想一打开就只要有另外的办法了,你可以修改注册表,把他的关联文件设置为你的程序,然后在调用原来的设置,
如一个文本文档,你就先调用你的程序,然后在你的程序里面调用记事本.这个办法比较号,但是要防止人家修改注册表.
Lo 2003-07-30
  • 打赏
  • 举报
回复
没有人帮忙吗?。。。

很久没来了,现在不会这么没人气了吧?

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧