Jump to content

FileSystemMonitor UDF partially broken in x64 environment. AutoIt v3.3.8.1


 Share

Recommended Posts

Hello,

I´m trying to use the FileSystemMonitor UDF from SeanGriffin released here:

The original thread seems like old and dead, but the functionality of this UDF is very useful.

(Actually, after some research, I found this the best and up-to-date solution available in Google.

Is there any other way to perform such task, like monitoring folder and files changes?)

That´s the original files from seangriffin´s topic:

Posted Image FileSystemMonitor example.au3 4.14K 1762 downloads

Latest Version - v0.4 (02/05/10)

Posted Image FileSystemMonitor.au3 15.25K 2181 downloads

There´s something weird with this UDF and examples.

I´m trying to run these here in my computer, but the "FileSystemMonitor example.au3" doesn't gives me much information.

Practically, it only gives something like this:

|Folder or non-folder has changed |SHCNEUPDATEITEM(0x00002000)| name and path of the file or folder, occasionally) |

Little vague isn't it? I can create, erase, update files (or folders) in the monitored folder, and the answer is always that above. How would I know if the changed object is a file or a folder? Or if it was created, erased or updated? (Although the info received about renaming files or folders is OK.)

The result described was compiled in x86 executable script.

(I tried to compile in x64 script, but it does not work at all.)

I tried to run with admin rights and without it, same result.

I´m using:

Windows Vista’s’ Home Premium Service Pack 2 - x64

Notebook HP dv6750br - Processor: AMD Turion™ 64 X2 Mobile Technology TL-58 1,90 GHz

Memory (RAM): 4,00 GB - Brazilian keyboard.

and AutoIt v3.3.8.1

In the image below, I created the ww.txt, edited with Word, and after, edited with Notepad.

(You can´t tell what I did just seeing the log.)

Posted Image

I will be thankful with any help.

[]s

Retrocomp

Link to comment
Share on other sites

  • Moderators

RetroComp,

I use a slightly modified version of this UDF with great success to check on changes to files. Try running these 2 and see if you get better results:

The UDF (save it as FileSystemMonitor_Mod.au3):

#include-once

#cs
    Title:           File System Monitoring UDF Library for AutoIt3
    Filename:          FileSystemMonitor.au3
    Description:     A collection of functions for monitoring the Windows File System
    Author:           seangriffin
    Version:          V0.4
    Last Update:     02/05/10
    Requirements:     AutoIt3 3.2 or higher
#ce

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; #INCLUDES# =========================================================================================================

; #GLOBAL VARIABLES# =================================================================================================
Global $pFSM_DirEvents, $pFSM_Dir, $pFSM_Overlapped, $tFSM_FNI, $pFSM_Buffer, $sFSM_Filename, $aFSM_Register, $iFSM_Buffersize, $tFSM_Overlapped
Global $tFSM_Buffer, $tFSM_DirEvents, $iFSM_DirEvents, $hFSM_Event, $hFSM_ShellMonGUI = GUICreate("")

; #FUNCTION# ;===============================================================================
;
; Name...........: _FileSysMonSetup()
; Description ...: Setup File System Monitoring.
; Syntax.........: _FileSysMonSetup($iMonitor_Type = 3, $sDirMon_Path = "C:\", $sShellMon_Path = "")
; Parameters ....: $iMonitor_Type - Optional: The type of monitoring to use.
;                      1 = directory monitoring only
;                      2 = shell monitoring only
;                      3 = both directory and shell monitoring
;                  $sDirMon_Path - Optional: The path to use for directory monitoring.
;                      The path "C:\" is used if one isn't provided.
;                  $sShellMon_Path - Optional: The path to use for shell monitoring.
;                      The blank path is used if one isn't provided. This
;                      denotes that system-wide shell events will be monitored.
; Return values .: On Success            - Returns True.
;                  On Failure            - Returns False.
; Author ........: seangriffin
; Modified.......:
; Remarks .......: A call to this function should be inserted in a script prior to calling other
;                  functions in this UDF.  Ideally the function should be placed before
;                  the main message loop in a GUI-based script.
; Related .......:
; Link ..........:
; Example .......: Yes
; ;==========================================================================================
Func _FileSysMonSetup($iMonitor_Type = 3, $sDirMon_Path = "C:\", $sShellMon_Path = "")

    If BitAnd($iMonitor_Type, 1) Then ; Setup the Directory Event Handler
        Local $sdir = $sDirMon_Path
        $tFSM_Buffer = DllStructCreate("byte[4096]")
        $pFSM_Buffer = DllStructGetPtr($tFSM_Buffer)
        $iFSM_Buffersize = DllStructGetSize($tFSM_Buffer)
        $tFSM_FNI = 0
        $pFSM_Dir = DllCall("kernel32.dll", "hwnd", "CreateFile", "Str", $sdir, "Int", 0x1, "Int", BitOR(0x1, 0x4, 0x2), "ptr", 0, "int", 0x3, "int", BitOR(0x2000000, 0x40000000), "int", 0)
        $pFSM_Dir = $pFSM_Dir[0]
        $tFSM_Overlapped = DllStructCreate("Uint OL1;Uint OL2; Uint OL3; Uint OL4; hwnd OL5")
        For $i = 1 To 5
            DllStructSetData($tFSM_Overlapped, $i, 0)
        Next
        $pFSM_Overlapped = DllStructGetPtr($tFSM_Overlapped)
        $tFSM_DirEvents = DllStructCreate("hwnd DirEvents")
        $pFSM_DirEvents = DllStructGetPtr($tFSM_DirEvents)
        Local $hFSM_Event = DllCall("kernel32.dll", "hwnd", "CreateEvent", "UInt", 0, "Int", True, "Int", False, "UInt", 0)
        DllStructSetData($tFSM_Overlapped, 5, $hFSM_Event[0])
        DllStructSetData($tFSM_DirEvents, 1, $hFSM_Event[0])
        DllCall("kernel32.dll", "Int", "ReadDirectoryChangesW", "hwnd", $pFSM_Dir, "ptr", $pFSM_Buffer, "dword", $iFSM_Buffersize, "int", False, "dword", BitOR(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x100), "Uint", 0, "Uint", $pFSM_Overlapped, "Uint", 0)
        $sFSM_Filename = ""
    EndIf

    If BitAND($iMonitor_Type, 2) Then ; Setup the Shell Event Handler
        ; Register a window message to associate an AutoIT function with the change notification events
        Local $aRet = DllCall("user32.dll", "uint", "RegisterWindowMessageW", "wstr", "shchangenotifymsg")
        If @error Then Return SetError(@error, @extended, 0)
        Local $SHNOTIFY = $aRet[0]
        GUIRegisterMsg($SHNOTIFY, "_FileSysMonShellEventHandler")
        ; Setup the structure for registering the gui to receive shell notifications
        If StringCompare($sShellMon_Path, "") <> 0 Then
            Local $ppidl = DllCall("shell32.dll", "ptr", "ILCreateFromPath", "wstr", $sShellMon_Path)
        EndIf
        Local $shnotifystruct = DllStructCreate("ptr pidl; int fRecursive")
        If StringCompare($sShellMon_Path, "") <> 0 Then
            DllStructSetData($shnotifystruct, "pidl", $ppidl[0])
        Else
            DllStructSetData($shnotifystruct, "pidl", 0)
        EndIf
        DllStructSetData($shnotifystruct, "fRecursive", 0)
        ; Register the gui to receive shell notifications
        $aFSM_Register = DllCall("shell32.dll", "int", "SHChangeNotifyRegister", "hwnd", $hFSM_ShellMonGUI, "int", BitOR(0x0001, 0x0002), "long", 0x7FFFFFFF, "uint", $SHNOTIFY, "int", 1, "ptr", DllStructGetPtr($shnotifystruct))
        If StringCompare($sShellMon_Path, "") <> 0 Then
            DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $ppidl[0])
        EndIf
    EndIf

    Return True
EndFunc   ;==>_FileSysMonSetup

; #FUNCTION# ;===============================================================================
;
; Name...........: _FileSysMonSetDirMonPath()
; Description ...: Change the path of Directory Monitoring
; Syntax.........: _FileSysMonSetDirMonPath($sDirMon_Path = "C:\")
; Parameters ....: $sDirMon_Path - Optional: The path to use for directory monitoring.
;                      The path "C:\" is used if one isn't provided.
; Return values .: On Success - Returns True.
;                  On Failure - Returns False.
;
; Author ........: seangriffin
; Modified.......:
; Remarks .......: For an unknown reason, after this function is called the
;
; Related .......:
; Link ..........:
; Example .......: Yes
; ;==========================================================================================
Func _FileSysMonSetDirMonPath($sDirMon_Path = "C:\")

    Local $sdir = $sDirMon_Path
    $pFSM_Dir = DllCall("kernel32.dll", "hwnd", "CreateFile", "Str", $sdir, "Int", 0x1, "Int", BitOR(0x1, 0x4, 0x2), "ptr", 0, "int", 0x3, "int", BitOR(0x2000000, 0x40000000), "int", 0)
    $pFSM_Dir = $pFSM_Dir[0]
    For $i = 1 To 5
        DllStructSetData($tFSM_Overlapped, $i, 0)
    Next
    Local $hFSM_Event = DllCall("kernel32.dll", "hwnd", "CreateEvent", "UInt", 0, "Int", True, "Int", False, "UInt", 0)
    DllStructSetData($tFSM_Overlapped, 5, $hFSM_Event[0])
    DllStructSetData($tFSM_DirEvents, 1, $hFSM_Event[0])
    DllCall("kernel32.dll", "Int", "ReadDirectoryChangesW", "hwnd", $pFSM_Dir, "ptr", $pFSM_Buffer, "dword", $iFSM_Buffersize, "int", False, "dword", BitOR(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x100), "Uint", 0, "Uint", $pFSM_Overlapped, "Uint", 0)

    Return True
EndFunc   ;==>_FileSysMonSetDirMonPath

; #FUNCTION# ;===============================================================================
;
; Name...........: _FileSysMonSetShellMonPath()
; Description ...: Change the path of Shell Monitoring
; Syntax.........: _FileSysMonSetShellMonPath($sDirMon_Path = "")
; Parameters ....: $sDirMon_Path    - Optional: The path to use for shell monitoring.
;                      The path "" is used if one isn't provided.
; Return values .: On Success - Returns True.
;                  On Failure - Returns False.
;
; Author ........: seangriffin
; Modified.......:
; Remarks .......:
;
; Related .......:
; Link ..........:
; Example .......: Yes
; ;==========================================================================================
Func _FileSysMonSetShellMonPath($sShellMon_Path = "")

    ; De-Register the gui from receiving shell notifications
    DllCall("shell32.dll", "int", "SHChangeNotifyDeregister", "ulong", $aFSM_Register[0])
    ; Register a window message to associate an AutoIT function with the change notification events
    ;Local $SHNOTIFY = _WinAPI_RegisterWindowMessage("shchangenotifymsg")
    Local $aRet = DllCall("user32.dll", "uint", "RegisterWindowMessageW", "wstr", "shchangenotifymsg")
    If @error Then Return SetError(@error, @extended, 0)
    Local $SHNOTIFY = $aRet[0]
    GUIRegisterMsg($SHNOTIFY, "_FileSysMonShellEventHandler")
    ; Setup the structure for registering the gui to receive shell notifications
    If StringCompare($sShellMon_Path, "") <> 0 Then
        Local $ppidl = DllCall("shell32.dll", "ptr", "ILCreateFromPath", "wstr", $sShellMon_Path)
    EndIf
    Local $shnotifystruct = DllStructCreate("ptr pidl; int fRecursive")
    If StringCompare($sShellMon_Path, "") <> 0 Then
        DllStructSetData($shnotifystruct, "pidl", $ppidl[0])
    Else
        DllStructSetData($shnotifystruct, "pidl", 0)
    EndIf
    DllStructSetData($shnotifystruct, "fRecursive", 0)
    ; Register the gui to receive shell notifications
    $aFSM_Register = DllCall("shell32.dll", "int", "SHChangeNotifyRegister", "hwnd", $hFSM_ShellMonGUI, "int", BitOR(0x0001, 0x0002), "long", 0x7FFFFFFF, "uint", $SHNOTIFY, "int", 1, "ptr", DllStructGetPtr($shnotifystruct))
    If StringCompare($sShellMon_Path, "") <> 0 Then
        DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $ppidl[0])
    EndIf

    Return True

EndFunc   ;==>_FileSysMonSetShellMonPath

; #FUNCTION# ;===============================================================================
;
; Name...........: _FileSysMonDirEventHandler()
; Description ...: Monitors the file system for changes to a given directory.  If a change event occurs,
;                      the user-defined "_FileSysMonActionEvent" function is called.
; Syntax.........: _FileSysMonDirEventHandler()
; Parameters ....: none
; Return values .: On Success - Returns True.
;                  On Failure - Returns False.
;
; Author ........: seangriffin
; Modified.......:
; Remarks .......: This function utilises the "ReadDirectoryChangesW" Win32 operating system function to
;                  monitor the a directory for changes.
;
;                  The ReadDirectoryChangesW function appears to queue events, such that whenever
;                  it is called, all unprocessed events are retrieved one at a time.
;
;                  The function "_FileSysMonSetup" must be called, with a $iMonitor_Type
;                  of either 1 or 3, prior to calling this    function.
;
;                  A call to this function should be inserted within the main message loop of a GUI-based script.
;
;                  A user-defined function to action the events is required to be created by the user
;                  in the calling script, and must be defined as follows:
;
;                  Func _FileSysMonActionEvent($event_type, $event_id, $event_value)
;
;                  EndFunc
;
; Related .......:
; Link ..........:
; Example .......: Yes
; ;==========================================================================================
Func _FileSysMonDirEventHandler()

    Local $aRet, $iOffset, $nReadLen, $tStr, $iNext, $ff

    $aRet = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", "dword", 1, "ptr", $pFSM_DirEvents, "dword", 100, "dword", 0x4FF, "dword", 0x6)

    If $aRet[0] = 0 Then
        $iOffset = 0
        $nReadLen = 0
        DllCall("kernel32.dll", "Uint", "GetOverlappedResult", "hWnd", $pFSM_Dir, "Uint", $pFSM_Overlapped, "UInt*", $nReadLen, "Int", True)
        While 1
            $tFSM_FNI = DllStructCreate("dword Next;dword Action;dword FilenameLen", $pFSM_Buffer + $iOffset)
            $tStr = DllStructCreate("wchar[" & DllStructGetData($tFSM_FNI, "FilenameLen") / 2 & "]", $pFSM_Buffer + $iOffset + 12)
            $sFSM_Filename = DllStructGetData($tStr, 1)
            _FileSysMonActionEvent(0, DllStructGetData($tFSM_FNI, "Action"), $sFSM_Filename)
            $iNext = DllStructGetData($tFSM_FNI, "Next")
            If $iNext = 0 Then ExitLoop
            $iOffset += $iNext
        WEnd
        $ff = DllStructGetData($tFSM_Overlapped, 5)
        DllCall("kernel32.dll", "Uint", "ResetEvent", "UInt", $ff)
        DllCall("kernel32.dll", "Int", "ReadDirectoryChangesW", "hwnd", $pFSM_Dir, "ptr", $pFSM_Buffer, "dword", $iFSM_Buffersize, "int", False, "dword", BitOR(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x100), "Uint", 0, "Uint", $pFSM_Overlapped, "Uint", 0)
    EndIf

    Return True

EndFunc   ;==>_FileSysMonDirEventHandler

; #FUNCTION# ;===============================================================================
;
; Name...........: _FileSysMonShellEventHandler()
; Description ...: Monitors the file system for shell events.
; Syntax.........: _FileSysMonShellEventHandler()
; Parameters ....: $hWnd   - The Window handle of the GUI in which the message appears.
;                  $iMsg    - The Windows message ID.
;                  $wParam - The first message parameter as hex value.
;                  $lParam - The second message parameter as hex value.
; Return values .: On Success - Returns True.
;                  On Failure - Returns False.
;
; Author ........: seangriffin
; Modified.......:
; Remarks .......: If a directory was provided in "_FileSysMonSetup" then only events in
;                  that directory will be caught.  If no directory was provided, then
;                  system-wide events will be caught.
;
;                  This function utilises the "SHChangeNotifyRegister" Win32 operating system functionality
;                  monitor a system or directory for changes relating to the Windows shell.
;
;                  The function "_FileSysMonSetup" must be called, with a $iMonitor_Type
;                  of either 2 or 3, prior to calling this    function.
;
;                  A call to this function is not required.  It is triggered automatically
;                  for each new shell event.
;
;                  A user-defined function to action the events is required to be created by the user
;                  in the calling script, and must be defined as follows:
;
;                  Func _FileSysMonActionEvent($event_type, $event_id, $event_value)
;
;                  EndFunc
;
; Related .......:
; Link ..........:
; Example .......: Yes
; ;==========================================================================================
Func _FileSysMonShellEventHandler($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg

    Local $tDestination, $wHighBit

    Local $tPath = DllStructCreate("dword dwItem1; dword dwItem2", $wParam)
    Local $aRet = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", DllStructGetData($tPath, "dwItem1"), "str", "")
    ; Get the drive for which free space has changed
    If $lParam = 0x00040000 Then
        $tDestination = DllStructCreate("long")
        DllCall("kernel32.dll", "none", "RtlMoveMemory", "ptr", DllStructGetPtr($tDestination), "ptr", (DllStructGetData($tPath, "dwItem1") + 2), "int", 4) ; CopyMemory
        $wHighBit = Int(Log(DllStructGetData($tDestination, 1)) / Log(2))
        $aRet[2] = Chr(65 + $wHighBit)
    EndIf
    If $lParam <> 0x00000002 And $lParam <> 0x00000004 Then ; FILE_ACTION_ADDED & FILE_ACTION_REMOVED skipped due to a deadlock with Directory_Event_Handler()
        _FileSysMonActionEvent(1, $lParam, $aRet[2])
    EndIf

    Return True

EndFunc   ;==>_FileSysMonShellEventHandler

And the example:

#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListviewConstants.au3>
#Include <GuiListView.au3>
#include <WindowsConstants.au3>
#include "FileSystemMonitor_Mod.au3"

dim $msg

; GUI Setup

$main_gui = GUICreate("Shell Notification Monitor (Press ESC to close)", 800, 320, -1, -1, -1, $WS_EX_TOPMOST)
$path_input = GUICtrlCreateInput("M:\", 10, 10, 320)
$use_path_button = GUICtrlCreateButton("Use Path", 350, 10)
$listview = GUICtrlCreateListView("", 10, 40, 780, 250, $LVS_REPORT)
_GUICtrlListView_SetUnicodeFormat($listview, False)
_GUICtrlListView_InsertColumn($listview, 0, "Type", 200)
_GUICtrlListView_InsertColumn($listview, 1, "Name (Hex)", 200)
_GUICtrlListView_InsertColumn($listview, 2, "Value", 200)
_GUICtrlListView_InsertColumn($listview, 3, "Time", 100)
GUISetState(@SW_SHOW)

; Setup File System Monitoring
_FileSysMonSetup(3, "M:\", "")

; Main Loop

While 1

    ; Handle Directory related events
    _FileSysMonDirEventHandler()

    If $msg = $use_path_button then

        _FileSysMonSetDirMonPath(GUICtrlRead($path_input))
        _FileSysMonSetShellMonPath(GUICtrlRead($path_input))
    EndIf

    If $msg = $GUI_EVENT_CLOSE then

        ExitLoop
    EndIf

    $msg = GUIGetMsg()
WEnd

Func _FileSysMonActionEvent($event_type, $event_id, $event_value)

    ConsoleWrite($event_type & " - " & $event_id & " - " & $event_value & @CRLF)

    Local $event_type_name
    Local $fs_event = ObjCreate("Scripting.Dictionary")

    Switch $event_type

        Case 0

            $fs_event.item(Hex(0x00000001)) = "file added to the directory|FILE_ACTION_ADDED"
            $fs_event.item(Hex(0x00000002)) = "file removed from the directory|FILE_ACTION_REMOVED"
            $fs_event.item(Hex(0x00000003)) = "file was modified|FILE_ACTION_MODIFIED"
            $fs_event.item(Hex(0x00000004)) = "file was renamed old name|FILE_ACTION_RENAMED_OLD_NAME"
            $fs_event.item(Hex(0x00000005)) = "file was renamed new name|FILE_ACTION_RENAMED_NEW_NAME"

        Case 1

            $fs_event.item(Hex(0x00000001)) = "Non-folder item name changed|SHCNE_RENAMEITEM"
            $fs_event.item(Hex(0x00000002)) = "Non-folder item created|SHCNE_CREATE"
            $fs_event.item(Hex(0x00000004)) = "Non-folder item deleted|SHCNE_DELETE"
            $fs_event.item(Hex(0x00000008)) = "Folder created|SHCNE_MKDIR"
            $fs_event.item(Hex(0x00000010)) = "Folder removed|SHCNE_RMDIR"
            $fs_event.item(Hex(0x00000020)) = "Storage media inserted into a drive|SHCNE_MEDIAINSERTED"
            $fs_event.item(Hex(0x00000040)) = "Storage media removed from a drive|SHCNE_MEDIAREMOVED"
            $fs_event.item(Hex(0x00000080)) = "Drive removed|SHCNE_DRIVEREMOVED"
            $fs_event.item(Hex(0x00000100)) = "Drive added|SHCNE_DRIVEADD"
            $fs_event.item(Hex(0x00000200)) = "Local computer folder shared via the network|SHCNE_NETSHARE"
            $fs_event.item(Hex(0x00000400)) = "Local computer folder not shared via the network|SHCNE_NETUNSHARE"
            $fs_event.item(Hex(0x00000800)) = "Item or folder attributes have changed|SHCNE_ATTRIBUTES"
            $fs_event.item(Hex(0x00001000)) = "Folder content has changed|SHCNE_UPDATEDIR"
            $fs_event.item(Hex(0x00002000)) = "Folder or non-folder has changed|SHCNE_UPDATEITEM"
            $fs_event.item(Hex(0x00004000)) = "Computer disconnected from server|SHCNE_SERVERDISCONNECT"
            $fs_event.item(Hex(0x00008000)) = "System image list image has changed|SHCNE_UPDATEIMAGE"
            $fs_event.item(Hex(0x00010000)) = "Not used|SHCNE_DRIVEADDGUI"
            $fs_event.item(Hex(0x00020000)) = "Folder name has changed|SHCNE_RENAMEFOLDER"
            $fs_event.item(Hex(0x00040000)) = "Drive free space has changed|SHCNE_FREESPACE"
            $fs_event.item(Hex(0x0002381F)) = "SHCNE_DISKEVENTS"
            $fs_event.item(Hex(0x0C0581E0)) = "SHCNE_GLOBALEVENTS"
            $fs_event.item(Hex(0x7FFFFFFF)) = "SHCNE_ALLEVENTS"
            $fs_event.item(Hex(0x80000000)) = "SHCNE_INTERRUPT"
    EndSwitch

    if StringLen($fs_event.item(Hex(Int($event_id)))) > 0 Then

        $event_type_name = StringSplit($fs_event.item(Hex(Int($event_id))), "|")
        $event_type_name[2] = $event_type_name[2] & "(" & $event_id & ")"

        _GUICtrlListView_InsertItem($listview, $event_type_name[1], 0)
        _GUICtrlListView_SetItemText($listview, 0, $event_type_name[2], 1)
        _GUICtrlListView_SetItemText($listview, 0, $event_value, 2)
        _GUICtrlListView_SetItemText($listview, 0, @HOUR & ":" & @MIN & ":" & @SEC, 3)
    EndIf
EndFunc

I get console reports like this:

Event ID: 2
fred4.au3.2.bak deleted

How do you get on? :)

M23

Edited by Melba23
Amended code for Hex function

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi Melba23,

Thanks for responding and thanks for the code.

I´m testing your version and example and it is all simpler to understand the results.

Although, I still have some questions about your version.

1. Is there a way to know if the triggered event was for a file or a folder?

2. The same event (ex: deleting a folder) is triggered more than once. Is it normal?

3. How know I if a file was renamed? What are the other Event ID codes?

4. Your mod example uses only the "directory monitoring". When (and why, and how) should I use the shell monitoring?

Again, thanks for helping.

[]s RetroComp

Link to comment
Share on other sites

  • Moderators

RetroComp,

I am afraid I cannot answer all of your questions as I did not write the UDF - all I did was to rehash the code so I see how I could use it a bit better and write a clearer example. My usage of the UDF has been to detect changes to a given folder when files are modified by external processes - and for that I have found it very useful and reliable. :)

But I will have a go - just accept that these are hobbyist comments and by no means definitive:

1. I do not believe you can. You woudl have to use FileGetAttrib on the path and see if you got a "D" returned.

2. I have often found a fair few events triggered by actions on the folder content. To be honest I never looked further than "1/2/Else" as that gave me "created/deleted/modified" - and that was enough. I seem to remember that some of the others were changes to folder size and content - no doubt MSDN could provide more details but I tend to regard that place "shark-infested custard" to be avoided if at all possible. ;)

3. See answer to 2.

4. I have not used "shell monitoring" other than running the posted UDF example. I seem to remember that it allows you to detect wider events that affect the entire drive - but as you found with far less detail on what exactly happened - whereas "directory monitoring" is limited to the specific folder designated by the user.

Sorry if that appears a bit thin - but I have not really played with the UDF for some time. seangriffin is not a frequent visitor to the forum these days - but if you want to come up with some specific scenarios I would be happy to try and work through them with you. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

M23,

I´m trying to capture a printer spool from DOSBOX. To capture the file prints tossed from DOSBOX and print in Windows.

Thanks for the clarification. I'll go with your FileGetAttrib tip for now.

It is to avoid my program trying to print a created Folder instead a file, for example :)

And it needs to print only freshly created files, never files altered or renamed by the user.

Is there a way to get in touch with the seangriffin?

I´m thinking about getting a ticket from Bugtracker, and send a formal bug report to Autoit programmers.

I do believe this monitor function is very and broadly useful, and should become an "Standard UDF" and maintained properly as this. (Who knows, maybe I get the people in good mood and this works.)

[]s RetroComp

Link to comment
Share on other sites

I do believe this monitor function is very and broadly useful, and should become an "Standard UDF" and maintained properly as this. (Who knows, maybe I get the people in good mood and this works.)

Please pay close attention to the red box, if you're submitting the UDF because you want a Dev/MVP to fix any issues with the UDF, then I would urge you to reconsider your proposal. Thanks for listening.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

  • Moderators

RtroComp,

I´m thinking about getting a ticket from Bugtracker, and send a formal bug report to Autoit programmers

I would not do that if I were you - as you would receive very short shrift from the AutoIt upper levels (including me!). Bug reports are for the core functions and the UDFs that are installed with AutoIt only. We have enough problems keeping them up-to-date without taking on all the UDFs posted in the example section. :mad:

You can only hope that the author responds to any comments you post in the Examples thread where the UDF was released - we have no way of contacting members other than via the forum itself. That is one reason why I rewrote the UDF and example so that I could better understand what it did and how to use it. So I suggest that you limit your activity to getting it to work as you wish (as I said earlier I am quite willing to help out) and then publish your own version - which you will have to maintain. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Well...

Ok, I give up. I understood the situation. :laser::lol:

I will play around with the M23 version and post any new results only here.

(Although the dll calls are kind of beyond my programmer limits.)

I appreciate (very very much) your help offer, so, I will return if I get stuck in any point. :D

Good vibes.

Retrocomp.

Edited by RetroComp
Link to comment
Share on other sites

  • 1 month later...

RetroComp,

I am afraid I cannot answer all of your questions as I did not write the UDF - all I did was to rehash the code so I see how I could use it a bit better and write a clearer example. My usage of the UDF has been to detect changes to a given folder when files are modified by external processes - and for that I have found it very useful and reliable. :)

Hi Melba

As per your suggestion in another thread, I followed that and this topic up to here, and also downloaded/tested the examples there.

But as pointed by others during this thread, messages anre not very clear if a file was deleted and so on.

I´m not new to AU3 forum..... but unfortunatedly when it comes to ObjCreate or "similar" issues I get in some trouble.

I found in MSDN a function? (FileSystemWatcher Class) from system.IO , that seems to answer this issue.

Also, examples on it´s use: http://www.blackwasp.co.uk/FileSystemWatcher.aspx continuing in http://www.blackwasp.co.uk/FileSystemWatcher_2.aspx

For what is told in FileSystemWatcher Class, it seems that just with it all questions about file changes are answered. But, for me, that have no C, neither knowledge to put it´s specification in AU3, I can´t know if it realy is the answer or not.

So, if anyone with more knowledge on how to put that "call" in AU3 could help, that would br great. After that, if desired, I can try to go forward...

Thanks in advance

Jose

Edited by joseLB
Link to comment
Share on other sites

  • Moderators

joseLB,

The Hex change has struck again - the script was not correctly dealing with the folder events. Please try the amended script in post #2 above - you should find that you now get a lot more info on actions occuring in the followed folder. :)

Sorry about that - the changes to the Hex function were necessary, but they have really screwed up a lot of old scripts. ;)

M23

Edited by Melba23
Typo

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

joseLB,

The Hex change has struck again - the script was not correctly dealing with the folder events. Please try the amended script in post #2 above - you should find that you now get a lot more info on actions occuring in the followed folder. :)

Sorry about that - the changes to the Hex function were necessary, but they have really screwed up a lot of old scripts. ;)

M23

Hi Melba, thanks

I tried it, but seems it still not working. So, I recorded a movie, so you can see if I´m doing something wrong. My note is a win7, homebasic, 64 bits.

http://www.docpro.com.br/multimidia/lixo1.html (excluir= delete)

see that this "teste" folder is a subfolder from the folder where the scripts are. After movie recording, I didnt stop the program, recorded the movie, save it, generate the html, swf, and other files, all in drive c, but none of these operations recordede a single line in program´s screen.

Jose

Edited by joseLB
Link to comment
Share on other sites

  • Moderators

joseLB,

You are not tracking folder events because you have not set the correct folder path when you initialise the system monitor. If you use the input in the example script to set the drive you do indeed track that drive, but the folder is unfortunately set to the root of that drive. :(

What you need to do is set the initial paths in the script before running it - I have just run the example below and got both shell and folder notifications when adding, modifying and deleting files within the defined folder: :)

; Setup File System Monitoring
_FileSysMonSetup(3, "M:\Program\Au3 Scripts", "M;\") ; <<<<<<< Set your folder and drive paths here

And also remember that you only get shell notifications if you really delete a file - sending it to the Recycle bin does not change the drive free space although you will get a folder event. ;)

So set the paths correctly and see what you get. You might also like to add this line to the _FileSysMonActionEvent function so you get a double display:

Func _FileSysMonActionEvent($event_type, $event_id, $event_value)

    ConsoleWrite($event_type & " - " & $event_id & " - " & $event_value & @CRLF)

This is a tricky UDF to use at first, but it works well once you get the hang of it. :)

M23

Edit:

If you change the example a bit you can use the folder path in the input and all works as you think it should:

If $msg = $use_path_button then
    $sFolder = GUICtrlRead($path_input)
    $sDrive = StringLeft($sFolder, 3)
    _FileSysMonSetDirMonPath($sFolder)
    _FileSysMonSetShellMonPath($sDrive)
EndIf
Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks Melba.

In parallel I ask a friend that uses C to compile and give me that example

The results are impressive. So, I uploaded the .exe so you can check

.exe => http://www.docpro.com.br/multimidia/FileSystemMonitor.exe

If you or others at forum found interesting,, what about to transcribe to au3? Unfortunatedly, as explained before, I´m unable to handle this tasl. Folows it in C as got from http://www.blackwasp.co.uk/FileSystemWatcher.aspx

I think this can be usefull for many others...

Jose

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace FileSystemMonitor
{
public partial class FileMonitorForm : Form
{
private FileSystemWatcher _watcher;



///
/// Basic constructor.
///
public FileMonitorForm()
{
InitializeComponent();

_watcher = new FileSystemWatcher();
_watcher.SynchronizingObject = this;

_watcher.Changed += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Created += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Deleted += new FileSystemEventHandler(LogFileSystemChanges);
_watcher.Renamed += new RenamedEventHandler(LogFileSystemRenaming);
_watcher.Error += new ErrorEventHandler(LogBufferError);
}



///
/// Log buffer overloading errors.
///
void LogBufferError(object sender, ErrorEventArgs e)
{
string log = string.Format("{0:G} | Buffer limit exceeded", DateTime.Now);
ChangeLogList.Items.Add(log);
}



///
/// Process renaming actions.
///
void LogFileSystemRenaming(object sender, RenamedEventArgs e)
{
string log = string.Format("{0:G} | {1} | Renamed from {2}", DateTime.Now, e.FullPath, e.OldName);
ChangeLogList.Items.Add(log);
}



///
/// Process creations, modifications and deletions.
///
void LogFileSystemChanges(object sender, FileSystemEventArgs e)
{
string log = string.Format("{0:G} | {1} | {2}", DateTime.Now, e.FullPath, e.ChangeType);
ChangeLogList.Items.Add(log);
}



///
/// Enables and disables the file system events.
///
private void MonitoringInput_CheckedChanged(object sender, EventArgs e)
{
string monitoredFolder = FolderInput.Text;
bool folderExists = Directory.Exists(monitoredFolder);

if (folderExists)
{
_watcher.Path = monitoredFolder;
_watcher.Filter = FileFilterInput.Text;
_watcher.IncludeSubdirectories = SubfoldersInput.Checked;

// Notification filters
NotifyFilters notificationFilters = new NotifyFilters();
if (AttributesInput.Checked) notificationFilters = notificationFilters | NotifyFilters.Attributes;
if (CreationTimeInput.Checked) notificationFilters = notificationFilters | NotifyFilters.CreationTime;
if (DirectoryNameInput.Checked) notificationFilters = notificationFilters | NotifyFilters.DirectoryName;
if (FileNameInput.Checked) notificationFilters = notificationFilters | NotifyFilters.FileName;
if (LastAccessInput.Checked) notificationFilters = notificationFilters | NotifyFilters.LastAccess;
if (LastWriteInput.Checked) notificationFilters = notificationFilters | NotifyFilters.LastWrite;
if (SecurityInput.Checked) notificationFilters = notificationFilters | NotifyFilters.Security;
if (SizeInput.Checked) notificationFilters = notificationFilters | NotifyFilters.Size;
_watcher.NotifyFilter = notificationFilters;

_watcher.EnableRaisingEvents = MonitoringInput.Checked;
}
else if (MonitoringInput.Checked)
{
MessageBox.Show(this, "The selected folder does not exist.", "Invalid Folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
MonitoringInput.Checked = false;
}

FolderInput.Enabled = FileFilterInput.Enabled = NotificationsGroup.Enabled = !MonitoringInput.Checked;
}



///
/// Launches the BlackWasp web site.
///
private void BlackWaspLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("http://www.blackwasp.co.uk/");
}
}
}
Edited by joseLB
Link to comment
Share on other sites

  • Moderators

joseLB,

Your exe works nicely, but I get even better returns from the UDF. ;)

Exe:

UDF:

So I do not see the need to convert the C code to AutoIt - the functionality already exists. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Thanks Melba, indeed....

But I noticed that if you move a file from a sub folder in the monitored folder to another monitored subfolder, messages vary a bit from one case to other. Also, seems to be dificult do identify both subfolder where it hapens.

I will do a more carefull look on this and post here.

In another direction: I don´t know if I will go this way or or not, bu do you know what is wrong ?

Local $oShell = ObjCreate("System.IO.FileSystemWatcher")

MsgBox(1,1,@error &amp; @cr&amp; $oShell) -> - 24...... and 0 error, and it didnt created the object

ps: I combined all possible ways the 3 items above, no succes, he, he...

when i look C (I know nothing of C) I see that it declares system.io before to create the object ( new ). But I think that in au3 I shoud put all 3 levels"

but

Local $oShell = ObjCreate("shell.application") ; Get the Windows Shell Object

MsgBox (1,1,@error &amp;@cr&amp; $oshell) => works ok

and also

$oSpeech = ObjCreate ( 'SAPI.SpVoice' ) works ok too.

Edited by joseLB
Link to comment
Share on other sites

  • 6 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...