Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Ett program kan övervaka innehållet i en katalog och dess underkataloger med hjälp av ändringsmeddelanden. Att vänta på ett ändringsmeddelande motsvarar att ha en läsåtgärd som väntar på en katalog och dess underkataloger, om det behövs. När något ändras i katalogen som övervakas slutförs läsåtgärden. Ett program kan till exempel använda dessa funktioner för att uppdatera en kataloglista när ett filnamn i den övervakade katalogen ändras.
Ett program kan ange en uppsättning villkor som utlöser ett ändringsmeddelande med hjälp av funktionen FindFirstChangeNotification. Villkoren omfattar ändringar av filnamn, katalognamn, attribut, filstorlek, tidpunkt för senaste skrivning och säkerhet. Den här funktionen returnerar också ett handtag som kan väntas på med hjälp av väntefunktioner. Om väntevillkoret är uppfyllt kan FindNextChangeNotification användas för att tillhandahålla en meddelandereferens för att vänta på efterföljande ändringar. Dessa funktioner anger dock inte den faktiska ändring som uppfyllde väntevillkoret.
Använd FindCloseChangeNotification för att stänga meddelandehandtaget.
Om du vill hämta information om den specifika ändringen som en del av meddelandet använder du funktionen ReadDirectoryChangesW. Med den här funktionen kan du också tillhandahålla en kompletteringsrutin.
Obs
Funktionerna FindFirstChangeNotification och ReadDirectoryChangesW är ömsesidigt uteslutande. Du bör använda det ena eller det andra, men inte båda.
Information om hur du spårar ändringar på en volym finns i ändra journaler.
I följande exempel övervakas katalogträdet för ändringar av katalognamn. Den övervakar också en katalog för filnamnsändringar. I exemplet används funktionen FindFirstChangeNotification för att skapa två notifikationshandtag och funktionen WaitForMultipleObjects för att vänta på att handtagen. När en katalog skapas eller tas bort i trädet bör exemplet uppdatera hela katalogträdet. När en fil skapas eller tas bort i katalogen bör exemplet uppdatera katalogen.
Not
Det här förenklade exemplet använder funktionen ExitProcess för avslutning och rensning, men mer komplexa program bör alltid använda korrekt resurshantering, till exempel FindCloseChangeNotification där det är lämpligt.
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
void RefreshDirectory(LPTSTR);
void RefreshTree(LPTSTR);
void WatchDirectory(LPTSTR);
void _tmain(int argc, TCHAR *argv[])
{
if(argc != 2)
{
_tprintf(TEXT("Usage: %s <dir>\n"), argv[0]);
return;
}
WatchDirectory(argv[1]);
}
void WatchDirectory(LPTSTR lpDir)
{
DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];
TCHAR lpDrive[4];
TCHAR lpFile[_MAX_FNAME];
TCHAR lpExt[_MAX_EXT];
_tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
lpDrive[2] = (TCHAR)'\\';
lpDrive[3] = (TCHAR)'\0';
// Watch the directory for file creation and deletion.
dwChangeHandles[0] = FindFirstChangeNotification(
lpDir, // directory to watch
FALSE, // do not watch subtree
FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes
if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
{
printf("\n ERROR: FindFirstChangeNotification function failed.\n");
ExitProcess(GetLastError());
}
// Watch the subtree for directory creation and deletion.
dwChangeHandles[1] = FindFirstChangeNotification(
lpDrive, // directory to watch
TRUE, // watch the subtree
FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir name changes
if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
{
printf("\n ERROR: FindFirstChangeNotification function failed.\n");
ExitProcess(GetLastError());
}
// Make a final validation check on our handles.
if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL))
{
printf("\n ERROR: Unexpected NULL from FindFirstChangeNotification.\n");
ExitProcess(GetLastError());
}
// Change notification is set. Now wait on both notification
// handles and refresh accordingly.
while (TRUE)
{
// Wait for notification.
printf("\nWaiting for notification...\n");
dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
FALSE, INFINITE);
switch (dwWaitStatus)
{
case WAIT_OBJECT_0:
// A file was created, renamed, or deleted in the directory.
// Refresh this directory and restart the notification.
RefreshDirectory(lpDir);
if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
{
printf("\n ERROR: FindNextChangeNotification function failed.\n");
ExitProcess(GetLastError());
}
break;
case WAIT_OBJECT_0 + 1:
// A directory was created, renamed, or deleted.
// Refresh the tree and restart the notification.
RefreshTree(lpDrive);
if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
{
printf("\n ERROR: FindNextChangeNotification function failed.\n");
ExitProcess(GetLastError());
}
break;
case WAIT_TIMEOUT:
// A timeout occurred, this would happen if some value other
// than INFINITE is used in the Wait call and no changes occur.
// In a single-threaded environment you might not want an
// INFINITE wait.
printf("\nNo changes in the timeout period.\n");
break;
default:
printf("\n ERROR: Unhandled dwWaitStatus.\n");
ExitProcess(GetLastError());
break;
}
}
}
void RefreshDirectory(LPTSTR lpDir)
{
// This is where you might place code to refresh your
// directory listing, but not the subtree because it
// would not be necessary.
_tprintf(TEXT("Directory (%s) changed.\n"), lpDir);
}
void RefreshTree(LPTSTR lpDrive)
{
// This is where you might place code to refresh your
// directory listing, including the subtree.
_tprintf(TEXT("Directory tree (%s) changed.\n"), lpDrive);
}