Earthshine Posted November 14, 2018 Share Posted November 14, 2018 (edited) why are you defining func _WinAPI_ReadDirectoryChanges?? start with the working sample expandcollapse popup#include <APIFilesConstants.au3> #include <Array.au3> #include <MsgBoxConstants.au3> #include <WinAPIError.au3> #include <WinAPIFiles.au3> #include <WinAPIMem.au3> Global $g_sPath = @TempDir & '\~TEST~' DirCreate($g_sPath) If Not FileExists($g_sPath) Then MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to create folder.') Exit EndIf OnAutoItExitRegister('OnAutoItExit') Local $hDirectory = _WinAPI_CreateFileEx($g_sPath, $OPEN_EXISTING, $FILE_LIST_DIRECTORY, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_FLAG_BACKUP_SEMANTICS) If @error Then _WinAPI_ShowLastError('', 1) EndIf Local $pBuffer = _WinAPI_CreateBuffer(8388608) Local $aData While 1 $aData = _WinAPI_ReadDirectoryChanges($hDirectory, BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME), $pBuffer, 8388608, 1) If Not @error Then _ArrayDisplay($aData, '_WinAPI_ReadDirectoryChanges') Else _WinAPI_ShowLastError('', 1) EndIf WEnd Func OnAutoItExit() DirRemove($g_sPath, 1) EndFunc ;==>OnAutoItExit then make your other script to actuate it. Edited November 14, 2018 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Developers Jos Posted November 14, 2018 Developers Share Posted November 14, 2018 Define still fails! SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
youtuber Posted November 14, 2018 Author Share Posted November 14, 2018 (edited) @Earthshine yes, but the gui doesn't respond and doesn't detect changes to the text document Spoiler expandcollapse popup#include <APIFilesConstants.au3> #include <Array.au3> #include <MsgBoxConstants.au3> #include <WinAPIError.au3> #include <WinAPIFiles.au3> #include <WinAPIMem.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <File.au3> Global $g_sPath = @DesktopDir & '\Changing folder' DirCreate($g_sPath) If Not FileExists($g_sPath) Then MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Unable to create folder.') Exit EndIf Global $pBuffer = _WinAPI_CreateBuffer(8388608) Global $aData OnAutoItExitRegister('OnAutoItExit') Global $hDirectory = _WinAPI_CreateFileEx($g_sPath, $OPEN_EXISTING, $FILE_LIST_DIRECTORY, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_FLAG_BACKUP_SEMANTICS) If @error Then _WinAPI_ShowLastError('', 1) EndIf $Form1 = GUICreate("Form1", 493, 263) $Edit1 = GUICtrlCreateEdit("" & @CRLF, 16, 24, 457, 193, BitOR($ES_MULTILINE, $ES_AUTOVSCROLL, $WS_VSCROLL)) GUISetState(@SW_SHOW, $Form1) While 1 $aData = _WinAPI_ReadDirectoryChanges($hDirectory, BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME), $pBuffer, 8388608, 1) If Not @error Then GUICtrlSetData($Edit1, @MIN & " : " & @SEC & " File has changed " & $aData & @CRLF, 1) Else _WinAPI_ShowLastError('', 1) EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func OnAutoItExit() DirRemove($g_sPath, 1) EndFunc ;==>OnAutoItExit Edited November 14, 2018 by youtuber Link to comment Share on other sites More sharing options...
Developers Jos Posted November 14, 2018 Developers Share Posted November 14, 2018 (edited) OK... this is my last contribution to this thread in an effort to make you realize what I have been telling you all the time! Copy it into SciTE. set the directory correct and press f5. Then watch the Console... and think about what you see. Then make some changes in the directory and look again to the Console and also the gui this time. expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <APIFilesConstants.au3> #include <Array.au3> #include <MsgBoxConstants.au3> #include <WinAPIError.au3> #include <WinAPIFiles.au3> #include <WinAPIMem.au3> Opt("GUIOnEventMode", 1) Global $ChangingFolder = @DesktopDir & "\Changing folder" Global $pBuffer = _WinAPI_CreateBuffer(8388608) Global $aData Global $hDirectory = _WinAPI_CreateFileEx($ChangingFolder, $OPEN_EXISTING, $FILE_LIST_DIRECTORY, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_FLAG_BACKUP_SEMANTICS) If @error Then _WinAPI_ShowLastError('', 1) EndIf $Form1 = GUICreate("Form1", 493, 263) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEButton") $Edit1 = GUICtrlCreateEdit("" & @CRLF, 16, 24, 457, 193, BitOR($ES_MULTILINE, $ES_AUTOVSCROLL, $WS_VSCROLL)) GUISetState(@SW_SHOW, $Form1) While 1 ConsoleWrite(" Wait for changes..") $aData = _WinAPI_ReadDirectoryChanges($hDirectory, BitOR($FILE_NOTIFY_CHANGE_DIR_NAME, $FILE_NOTIFY_CHANGE_LAST_WRITE, $FILE_NOTIFY_CHANGE_CREATION), $pBuffer, 8388608, 1) ConsoleWrite(" Something changed?") If Not @error and IsArray($aData) Then $curcontent=GUICtrlRead($Edit1) For $x = 1 to $aData[0][0] $curcontent &= @CRLF & $aData[$x][0] & " -> " & $aData[$x][1] Next GUICtrlSetData($Edit1, $curcontent, 1) Else _WinAPI_ShowLastError('', 1) EndIf WEnd Func CLOSEButton() ; Note: At this point @GUI_CtrlId would equal $GUI_EVENT_CLOSE, ; and @GUI_WinHandle would equal $hMainGUI Exit EndFunc ;==>CLOSEButton Jos Edited November 14, 2018 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
youtuber Posted November 14, 2018 Author Share Posted November 14, 2018 yes but still not responding to close gui Spoiler Link to comment Share on other sites More sharing options...
Zein Posted November 14, 2018 Share Posted November 14, 2018 (edited) 34 minutes ago, youtuber said: yes but still not responding to close gui Reveal hidden contents Hey, I'll try to explain in the simplest terms the issue you're facing. Jos's sample here loops to detect file changes. Something you are overlooking, is that "_WinAPI_ReadDirectoryChanges" will ONLY return after a change is made. That means when you put _WinAPI_ReadDirectoryChanges in your code, your script will WAIT until it returns before continuing. The only way it returns is if a file is changed. No file change? No script. That's fine, but with how this sample is written, once the _WinAPI_ReadDirectoryChanges call returns, we loop again due to "While 1" and it blocks once more, over and over again, no matter how many changes you make, until you manually queue the exit. Here is the workflow of the code you are sampling: Initiate GUI -> Wait for change in directory so _WinAPI_ReadDirectoryChanges can return -> Update GUI -> Repeat. Nothing in your script can run until _WinAPI_ReadDirectoryChanges returns. For this reason, the script will stop responding! That's what's giving you your error. Your script doesn't care about anything anymore EXCEPT waiting on _WinAPI_ReadDirectoryChanges! The way to get out of that, without editing Jos's sample is: After you try to exit the script, make one more change to the directory. This allowed _WinAPI_ReadDirectoryChanges to return and then lets your Exit code run right after, instead of looping again. This turns the execution to: Queue exit -> Wait for _WinAPI_ReadDirectoryChanges -> Run queued code directly after, which is exit If you just want to see Jos's example work, when you finish changing your files, try to close the GUI. Now you will see "Not Responding". Don't fret though, to get it to truly close, you need to make one more change in your directory. Once you save the change to the directory, the script will exit right away without any errors. What Jos is trying to tell you is that if you are making one script use _WinAPI_ReadDirectoryChanges, it will constantly block without having a good way to exit. The solution to this is to have another script that can act as a "controller" of sorts and use that to close the script running _WinAPI_ReadDirectoryChanges whenever you want, instead of getting stuck. @Jos if I have misinterpreted please let me know Edited November 14, 2018 by Zein Link to comment Share on other sites More sharing options...
youtuber Posted November 14, 2018 Author Share Posted November 14, 2018 (edited) _WinAPI_ReadDirectoryChanges,My fault is not my fault @AdamUL my script is still in the first message and still haven't changed actually I had a good working example. #include <Array.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Local $ChangingFolder = @DesktopDir & "\Changing folder" Global $sFileToCheck = $ChangingFolder & "\file.txt" Global $bFileChanged = False Global $sFileDateTime = _ArrayToString(FileGetTime($sFileToCheck)) AdlibRegister("_CheckFile", 250) $Form1 = GUICreate("Form1", 493, 263) $Edit1 = GUICtrlCreateEdit("" & @CRLF, 16, 24, 457, 193, BitOR($ES_MULTILINE, $ES_AUTOVSCROLL, $WS_VSCROLL)) GUISetState(@SW_SHOW, $Form1) While 1 If $bFileChanged Then GUICtrlSetData($Edit1, @MIN & " : " & @SEC & " File has changed " & $sFileToCheck & @CRLF, 1) $sFileDateTime = _ArrayToString(FileGetTime($sFileToCheck)) $bFileChanged = False EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _CheckFile() If $sFileDateTime <> _ArrayToString(FileGetTime($sFileToCheck)) Then $bFileChanged = True EndFunc ;==>_CheckFile but But I wanted for all txt files in a folder. And I'm still waiting for a solution, just for all txt files in a single folder. Edited November 14, 2018 by youtuber Link to comment Share on other sites More sharing options...
Developers Jos Posted November 14, 2018 Developers Share Posted November 14, 2018 (edited) 1 hour ago, youtuber said: yes but still not responding to close gui Correct... and what where you conclusions at each step I told you to do or do you want me to just burb up the working code for you? Quote And I'm still waiting for a solution, just for all txt files in a single folder. fuck it... you were told what the solution is but seem to refuse to follow all advice and pointers given... i am really done here now. Edited November 14, 2018 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Earthshine Posted November 14, 2018 Share Posted November 14, 2018 (edited) the example code works GREAT, returns ALL changes regardless. if you run the sample and dump files into that temp dir, they show up in the array just fine. lol. Jos' code works great too. Edited November 14, 2018 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Developers Jos Posted November 14, 2018 Developers Share Posted November 14, 2018 (edited) 18 minutes ago, Earthshine said: Jos' code works great too. It works sort-of as it returns all changes to the GUI but the GUI is unresponsive. I actually have the proper working code prepared but simply refuse to provide code to people unwilling to make any progress themselves first and make this a learning experience. Jos Edited November 14, 2018 by Jos Skeletor, Earthshine and FrancescoDiMuro 2 1 SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
Skeletor Posted November 15, 2018 Share Posted November 15, 2018 On 11/13/2018 at 10:20 PM, Jos said: Ah.. that's a good approach to life... when confused simply ignore it and it for sure will go away. @Jos , you on a roll today... Kind RegardsSkeletor "Coffee: my defense against going postal." Microsoft Office Splash Screen | Basic Notepad Program (Beginner) | Transparent Splash Screen | Full Screen UI Link to comment Share on other sites More sharing options...
youtuber Posted November 15, 2018 Author Share Posted November 15, 2018 (edited) Quote @Zein Here is the workflow of the code you are sampling:Initiate GUI -> Wait for change in directory so _WinAPI_ReadDirectoryChanges can return -> Update GUI -> Repeat. yes but i dont know how to disable _WinAPI_ReadDirectoryChanges and update gui function _WinAPI_ReadDirectoryChanges form1 gui for freezing GUIDelete or GUIRegisterMsg,give me a hint that I'm going to use something like that, very complicated for me, I am very confused. Edited November 15, 2018 by youtuber Link to comment Share on other sites More sharing options...
Zein Posted November 15, 2018 Share Posted November 15, 2018 1 hour ago, youtuber said: yes but i dont know how to disable _WinAPI_ReadDirectoryChanges and update gui function _WinAPI_ReadDirectoryChanges form1 gui for freezing GUIDelete or GUIRegisterMsg,give me a hint that I'm going to use something like that, very complicated for me, I am very confused. You disable it by finding a way to queue other code, and then forcing _WinAPI_ReadDirectoryChanges to return. One potential way to do this is by writing your script in two functions One function has the _WinAPI_ReadDirectoryChanges call, and the other function has the rest of your code. You could then bind that second function to a hotkey, and when you're done with _WinAPI_ReadDirectoryChanges you press the hotkey. Once you press the hotkey, force _WinAPI_ReadDirectoryChanges to return by making another change to the folder. Once the change is made, the function you bound to the hotkey will be called and your code will continue without losing responsiveness, all while being able to extract the results of _WinAPI_ReadDirectoryChanges. Of course, this is less than ideal for an automated program, but you can work off of this to find an automated approach. Link to comment Share on other sites More sharing options...
Simpel Posted November 16, 2018 Share Posted November 16, 2018 @youtuber, you seemed to be confused. You HAVE TO SPLIT that problem into 2 DIFFERENT SCRIPTS. Script 1 only looks for directory changes and stucks as long as there is no change and reports if there is a change. Script 2 is holding the responsive gui and waiting for a message that there is a change in the directory. If there is a change it has to inspect the directory and write the changes into the gui. The messages between both scripts are delivered by registry entries for lack of a better idea. At the end if you want to exit script 2 (and script 1 should exit too) you have to set the kill switch and then create a temp file in the directory with script 2 so that script 1 is able to react. Here is some pseudo code: expandcollapse popup#Region - Script 1 - Read Directory Changes #include <APIFilesConstants.au3> #include <FileConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPIDiag.au3> #include <WinAPIFiles.au3> #include <WinAPISys.au3> Global $g_sPathRegistry = ; same as in Script 2 Global $g_sPath = ; same as in Script 2 Local $hDirectory = _WinAPI_CreateFileEx($g_sPath, $OPEN_EXISTING, $FILE_LIST_DIRECTORY, BitOR($FILE_SHARE_READ, $FILE_SHARE_WRITE), $FILE_FLAG_BACKUP_SEMANTICS) If @error Then _WinAPI_ShowLastError('', 1) EndIf Local $pBuffer = _WinAPI_CreateBuffer(8388608) Local $aData While 1 ; !! Look exactly below if these are the parameters you want $aData = _WinAPI_ReadDirectoryChanges($hDirectory, BitOR($FILE_NOTIFY_CHANGE_FILE_NAME, $FILE_NOTIFY_CHANGE_DIR_NAME), $pBuffer, 8388608, 1) ; it will "loop" inside this function as long as there is no change!!! ; That part below will only be executed if there is any change in the directory regarding the parameters you defined above If Not @error Then _LookForKillSwitch() _SayScript2_ThatThereIsAChange() Else _WinAPI_ShowLastError('', 1) EndIf WEnd Func _SayScript2_ThatThereIsAChange() ; for lack of a better solution: RegWrite($g_sPathRegistry, "DirectoryChange", "REG_DWORD", 1) EndFunc Func _LookForKillSwitch() Local $bKillSwitch = RegRead($g_sPathRegistry, "KillSwitch") If $bKillSwitch Then Exit EndFunc #EndRegion #Region - Script 2 - React To Directory Changes Global $g_sPathRegistry = ; same as in Script 1 Global $g_sPath = ; same as in Script 1 RegWrite($g_sPathRegistry, "KillSwitch", "REG_DWORD", 0) ; reset RegWrite($g_sPathRegistry, "DirectoryChange", "REG_DWORD", 0) ; reset _ReadYourFilesHere() ; Create your GUI here _UpdateGUI() While 1 _IsThereAChangeInDirectory() Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _KillScript1() Exit EndSwitch Sleep(1000) ; to not read the registry permanently WEnd Func _ReadYourFilesHere() ; make a list of all files in the directory EndFunc Func _UpdateGUI() ; Update the list to your GUI or what ever is needed EndFunc Func _IsThereAChangeInDirectory() Local $bChange = RegRead($g_sPathRegistry, "DirectoryChange") If $bChange Then _ReadYourFilesHere() _UpdateGUI() EndIf EndFunc Func _KillScript1() RegWrite($g_sPathRegistry, "KillSwitch", "REG_DWORD", 1) ; set kill switch FileWrite($g_sPath & "/temp.txt", "Write some random stuff") ; Creates a file in $g_sPath, so that script 1 can react and can find kill switch While ProcessExists("Script1.exe") ; wait a bit WEnd FileDelete($g_sPath & "/temp.txt") EndFunc #EndRegion Regards, Simpel youtuber 1 SciTE4AutoIt = 3.7.3.0 AutoIt = 3.3.14.2 AutoItX64 = 0 OS = Win_10 Build = 19044 OSArch = X64 Language = 0407/german H:\...\AutoIt3\SciTE H:\...\AutoIt3 H:\...\AutoIt3\Include (H:\ = Network Drive) Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now