Skip to content

Instantly share code, notes, and snippets.

@mashingan
Last active January 14, 2021 17:59
Show Gist options
  • Save mashingan/4a31d3a630e22cf9274eebf475ee60e6 to your computer and use it in GitHub Desktop.
Save mashingan/4a31d3a630e22cf9274eebf475ee60e6 to your computer and use it in GitHub Desktop.
Monitor folder and files using in Windows
import winim
proc quit(value: DWORD) =
quit value.int
proc refreshDirectory(handle: var HANDLE) =
handle = FindFirstChangeNotification(".", false,
FILE_NOTIFY_CHANGE_FILE_NAME)
if handle == INVALID_HANDLE_VALUE:
quit GetLastError()
proc refreshTree(handle: var HANDLE) =
handle = FindFirstChangeNotification(".", true,
FILE_NOTIFY_CHANGE_DIR_NAME)
proc waitForMultipleObjects(count: int, handles: var openArray[HANDLE],
waitAll: bool, timeout: int32): int =
WaitForMultipleObjects(count.DWORD, addr handles[0], waitAll,
cast[DWORD](timeout)).int
proc main =
var
waitStatus: int
changeHandles: array[2, HANDLE]
refreshDirectory(changeHandles[0])
if changeHandles[0] == INVALID_HANDLE_VALUE:
echo "invalid handle value"
quit GetLastError()
refreshTree(changeHandles[1])
if changeHandles[1] == INVALID_HANDLE_VALUE:
echo "invalid handle value"
quit GetLastError()
echo "Start watching current directory"
while true:
waitStatus = waitForMultipleObjects(2, changeHandles, false, INFINITE)
case waitStatus
of WAIT_OBJECT_0:
echo "A file was created or deleted in this directory"
#refreshDirectory(changeHandles[0])
if FindNextChangeNotification(changeHandles[0]) == 0:
var lasterror = GetLastError()
echo "lasterror: ", lasterror
quit GetLastError()
#break
of WAIT_OBJECT_0 + 1:
echo "A folder was created or deleted in this directory"
#refreshTree(changeHandles[1])
if FindNextChangeNotification(changeHandles[1]) == 0:
var lasterror = GetLastError()
echo "lasterror: ", lasterror
quit GetLastError()
#break
else:
echo "Into default post"
quit GetLastError()
when isMainModule:
main()
# compile:
# > nim c -r monitorfile.nim
import winlean
const
FILE_NOTIFY_CHANGE_FILE_NAME* = 0x00000001'i32
FILE_NOTIFY_CHANGE_DIR_NAME* = 0x00000002'i32
FILE_NOTIFY_CHANGE_ATTRIBUTES* = 0x00000004'i32
FILE_NOTIFY_CHANGE_SIZE* = 0x00000008'i32
FILE_NOTIFY_CHANGE_LAST_WRITE* = 0x00000010'i32
FILE_NOTIFY_CHANGE_SECURITY* = 0x00000100'i32
{.push dynlib: "kernel32.dll", stdcall.}
proc findFirstChangeNotification(pathname: cstring, watchSubtree: bool,
notifFilter: int32): HANDLE {.importc: "FindFirstChangeNotificationA".}
proc findNextChangeNotification(handle: HANDLE): WINBOOL
{.importc:"FindNextChangeNotification".}
{.pop.}
proc quit(value: DWORD) =
quit value.int
proc refreshDirectory(handle: var HANDLE) =
handle = findFirstChangeNotification(".", false,
FILE_NOTIFY_CHANGE_FILE_NAME + FILE_NOTIFY_CHANGE_SIZE +
FILE_NOTIFY_CHANGE_LAST_WRITE)
if handle == INVALID_HANDLE_VALUE:
quit getLastError()
proc refreshTree(handle: var HANDLE) =
handle = findFirstChangeNotification(".", true,
FILE_NOTIFY_CHANGE_DIR_NAME)
proc waitForMultipleObjects(count: int, handles: var openArray[HANDLE],
waitAll: bool, timeout: int32): int =
echo "to wait for multiple objects"
winlean.waitForMultipleObjects(count.DWORD, cast[PWOHandleArray](addr handles[0]),
waitAll.WINBOOL, cast[DWORD](timeout)).int
proc main =
var
waitStatus: int
changeHandles: array[2, HANDLE]
refreshDirectory(changeHandles[0])
if changeHandles[0] == INVALID_HANDLE_VALUE:
echo "invalid handle value in refresh directory"
quit getLastError()
refreshTree(changeHandles[1])
if changeHandles[1] == INVALID_HANDLE_VALUE:
echo "invalid handle value in refresh tree"
quit getLastError()
echo "Start watching current directory"
while true:
# can handle INFINITE if doing in different thread
waitStatus = waitForMultipleObjects(2, changeHandles, false, 1000)
case waitStatus
of WAIT_OBJECT_0:
echo "A file was created or deleted in this directory"
#refreshDirectory(changeHandles[0])
if findNextChangeNotification(changeHandles[0]) == 0:
var lasterror = getLastError()
echo "lasterror: ", lasterror
quit getLastError()
#break
of WAIT_OBJECT_0 + 1:
echo "A folder was created or deleted in this directory"
#refreshTree(changeHandles[1])
if findNextChangeNotification(changeHandles[1]) == 0:
var lasterror = getLastError()
echo "lasterror: ", lasterror
quit getLastError()
#break
of WAIT_TIMEOUT:
echo "Nothing happened until time out happened"
else:
echo "Into default post"
quit getLastError()
when isMainModule:
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment