require 'Win32API' module Win32 INVALID_HANDLE_VALUE = -1 INFINITE = 0xFFFFFFFF WAIT_OBJECT_0 = 0x00000000 WAIT_TIMEOUT = 0x00000102 WAIT_FAILED = 0xFFFFFFFF FILE_NOTIFY_CHANGE_FILE_NAME = 0x00000001 FILE_NOTIFY_CHANGE_DIR_NAME = 0x00000002 FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x00000004 FILE_NOTIFY_CHANGE_SIZE = 0x00000008 FILE_NOTIFY_CHANGE_LAST_WRITE = 0x00000010 FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x00000020 FILE_NOTIFY_CHANGE_CREATION = 0x00000040 FILE_NOTIFY_CHANGE_SECURITY = 0x00000100 FindFirstChangeNotification = Win32API.new('kernel32', 'FindFirstChangeNotification', 'PIL', 'L') FindNextChangeNotification = Win32API.new('kernel32', 'FindNextChangeNotification', 'L', 'I') WaitForMultipleObjects = Win32API.new('kernel32', 'WaitForMultipleObjects', 'LPIL', 'L') WaitForSingleObject = Win32API.new('kernel32', 'WaitForSingleObject', 'LL', 'L') CloseHandle = Win32API.new('kernel32', 'CloseHandle', 'L', 'L') module Event def self.FindChangeNotification(directory = '.', watch_subtree = false) h = FindFirstChangeNotification.Call( directory, (watch_subtree ? 1 : 0), FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_CREATION # | #FILE_NOTIFY_CHANGE_FILE_NAME ) return nil if h == INVALID_HANDLE_VALUE begin loop { wait_start = Time.now return nil if WAIT_FAILED == WaitForSingleObject.Call(h, INFINITE) if block_given? yield if Time.now - wait_start > 0.1 else return true end return nil if 0 == FindNextChangeNotification.Call(h) } ensure CloseHandle.call(h) end end end end Win32::Event::FindChangeNotification('C:/AMP/apache/conf') { puts "changed" }