C ++ monitoring folder ()
First, we will introduce several important API functions:
Findfirstchangenotification ();
Findnextchangenotification ();
Waitforsingleobject ();
The lpzpath in findfirstchangenotification (lpzpath, fwatchsubtree, fdwfilter) indicates the path name to be monitored. fwatchsubtree determines whether to check the sub-directory, fdwfilter indicates the event to be monitored, and a handle is returned after the function is executed.
The value and meaning of the fdwfilter parameter are as follows:
File_policy_change_file_name
File_policy_change_dir_name
File_policy_change_size
File_policy_change_attributes
Findnextchangenotification (hchange), hchange is the handle returned by findfirstchangennotification, which is used by the request system
The handle of the change notification will be sent when the next change is detected. After the function is successfully returned, the application can wait for the Change Notification through waitformultipleobjects or waitfforsingleobject. In waitforsingleobject (hchange, dwmilliseconds), hchange is the handle returned by findfirstchangenotification. dwmilliseconds is the waiting time value and specifies the waiting time, in milliseconds. If the value is-1, the time is infinite. It is best to use findclosechangenotification (hchange) to close the handle before you end the monitoring program.
The following is a simple example. Its function is to monitor whether files in the C: \ pwin98 Directory have changed. If a RENAME, creation, or deletion occurs, use the Edit Control to display a prompt.
//
----------------
# Include
# Pragma hdrstop
# Include "unit1.h"
//----------------
# Pragma package (smart_init)
# Pragma resource "*. DFM"
Tform1 * form1;
//-----------------
_ Fastcall tform1: tform1 (tcomponent * owner)
: Tform (owner)
{
}
//-------------------
Void _ fastcall tform1: formcreate (tobject * sender)
{
DWORD dwwaitstatus;
Handle dwchangehandle; // handle of the returned notification
Dwchangehandle = findfirstchangenotification (
"C: \ pwin98", false, file_policy_change_file_name); // you can specify the handle for the returned notification.
If (dwchangehandle = invalid_handle_value)
// Determine whether the setting is successful
Exitprocess (getlasterror ());
While (true) {// sets the loop to monitor whether the loop exists
Dwwaitstatus = waitforsingleobject (dwchangehandle,-1); // return notification
Switch (dwwaitstatus ){
Case 0:
Edit1-> text = "something changed"; // a prompt is displayed.
Findclosechangenotification (dwcchangehandle); // close the handle
Exit (exit_success); // exit the program
Default:
Exitprocess (getlasterror ());
}
}
}
The program passed in C ++ builder4/pwin98. Because the C ++ Builder language is very standard, it is easy to extend it to other programming language environments.
This example shows how to monitor file changes in the hard disk. for the Registry, the regpolicychangekeyvalue () function can implement similar functions.
Method 2
Readdirectorychangesw function is mainly used.
# Include <windows. h>
# Include <stdio. h>
# Include <conio. h>
# Include <string. h>
Typedef struct parm
{
Char dir [128];
Handle hdir;
} Thread_param;
DWORD winapi thread (lpvoid lparam)
{
Thread_param * par = (thread_param *) lparam;
Char y [1024];
File_policy_information * pnotify = (file_policy_information *) Policy;
Char ansichar [3];
Wchar_t unicodechar [2];
DWORD cbbytes;
Printf ("watch [% s] Start. \ n", par-> DIR );
While (true)
{
If (readdirectorychangesw (par-> hdir,
& Policy,
Sizeof (notify ),
True,
File_policy_change_file_name |
File_policy_change_dir_name |
File_policy_change_attributes |
File_policy_change_size |
File_policy_change_last_write |
File_policy_change_last_access |
File_policy_change_creation |
File_policy_change_security,
& Cbbytes,
Null,
Null ))
{
Switch (pnotify-> action)
{
Case file_action_added:
Printf ("directory/file added -");
Break;
Case file_action_removed:
Printf ("directory/file removed -");
Break;
Case file_action_modified:
Printf ("directory/File Modified -");
Break;
Case file_action_renamed_old_name:
Printf ("directory/file old name -");
Break;
Case file_action_renamed_new_name:
Printf ("directory/file new name -");
Break;
}
Printf ("% S/", par-> DIR );
For (DWORD I = 0; I <pnotify-> filenamelength/2; I ++)
{
Unicodechar [0] = pnotify-> filename [I];
Unicodechar [1] = 0;
Zeromemory (ansichar, 3 );
Widechartomultibyte (cp_acp, 0, unicodechar,-1, ansichar, 3, null, null );
Printf ("% s", ansichar );
}
Printf ("\ n ");
}
}
}
Int main (INT argc, char ** argv)
{
DWORD threadid;
Thread_param par;
Handle hthread;
If (argc! = 2)
{
Printf ("dirwatch <directory> \ n ");
Return 0;
}
Lstrcpyn (par. dir, argv [1], 127 );
Par. hdir = createfile (
Par. dir, // pointer to the file name
File_list_directory, // access (read/write) Mode
File_cmd_read | file_cmd_write, // share mode
Null, // Security Descriptor
Open_existing, // how to create
File_flag_backup_semantics, // file attributes
Null // file with attributes to copy
);
If (par. hdir = invalid_handle_value)
{
Printf ("Open Directory [% s] fail. \ n", par. DIR );
Return 0;
}
If (par. hdir)
{
Printf ("Open Directory [% s] successfully. \ n", par. DIR );
}
Else
{
Printf ("Open Directory [% s] failed. \ n", par. DIR );
Return 0;
}
Hthread = createthread (null, 0, thread, (lpvoid *) & par, 0, & threadid );
If (hthread)
{
Printf ("createthread OK. \ n ");
Printf ("press <q> to quit. \ n ");
While (getch ()! = 'Q ');
Terminatethread (hthread, 0 );
Waitforsingleobject (hthread, 1000 );
Closehandle (par. hdir );
}
Else
{
Closehandle (par. hdir );
Printf ("createthread failed, the program exit. \ n ");
}
}