Created
January 16, 2012 19:12
-
-
Save NoxArt/1622439 to your computer and use it in GitHub Desktop.
Script to launch given shell command on directory/file change
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Beholder | |
* | |
* @author Jiri "NoxArt" Petruzelka | www.noxart.cz | [email protected] | |
* @author Microsoft | |
* | |
* @filesource | |
* | |
* @link http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261(v=vs.85).aspx | |
*/ | |
#include <windows.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <tchar.h> | |
#include <string> | |
using std::string; | |
string onChangeHandler; | |
bool debug = false; | |
void DirectoryChanged(LPTSTR); | |
void TreeChanged(LPTSTR); | |
void WatchDirectory(LPTSTR); | |
int _tmain(int argc, TCHAR *argv[]) | |
{ | |
if(argc != 3 && argc != 4) | |
{ | |
_tprintf(TEXT("Usage: %s <dir> <runOnChange> [debug]\n"), argv[0]); | |
return 0; | |
} | |
debug = (argc == 4); | |
if( debug ) | |
_tprintf(TEXT("[Beholder: running in DEBUG mode]")); | |
onChangeHandler = string(argv[2]); | |
WatchDirectory(argv[1]); | |
return 0; | |
} | |
void WatchDirectory(LPTSTR lpDir) | |
{ | |
DWORD dwWaitStatus; | |
HANDLE dwChangeHandles[2]; | |
TCHAR lpDrive[4]; | |
TCHAR lpFile[_MAX_FNAME]; | |
TCHAR lpExt[_MAX_EXT]; | |
_splitpath(lpDir, lpDrive, NULL, lpFile, lpExt); | |
lpDrive[2] = (TCHAR)'\\'; | |
lpDrive[3] = (TCHAR)'\0'; | |
// Watch the directory for file creation and deletion. | |
dwChangeHandles[0] = FindFirstChangeNotification( | |
lpDir, // directory to watch | |
TRUE, // do 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. | |
if(debug) | |
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. | |
DirectoryChanged(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. | |
TreeChanged(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("No changes in the timeout period.\n"); | |
break; | |
default: | |
printf("ERROR: Unhandled dwWaitStatus.\n"); | |
ExitProcess(GetLastError()); | |
break; | |
} | |
} | |
} | |
void DirectoryChanged(LPTSTR lpDir) | |
{ | |
if( debug ) | |
_tprintf(TEXT("Directory (%s) changed.\n"), lpDir); | |
else | |
system(onChangeHandler.c_str()); | |
} | |
void TreeChanged(LPTSTR lpDrive) | |
{ | |
if( debug ) | |
_tprintf(TEXT("Directory tree (%s) changed.\n"), lpDrive); | |
else | |
system(onChangeHandler.c_str()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment