WAITFOR, FOLDERMONITOR, and a file to change

Here's an example of how to use the Windows WAITFOR.EXE command with FOLDERMONITOR to wait for a file to change in TCC, do some processing, and continue monitoring for more changes in a file.

Code:
@setlocal
@echo off
::
:: To end this .btm, press either Ctrl-C or Ctrl-Break
::
on break goto Done
::
:: Remove monitor for e:\utils
::
foldermonitor /c e:\utils
::
:: Monitor the e:\utils\server.ini file for changes
:: When triggered, send the signal GetClipDone
::
foldermonitor e:\utils /i"server.ini" modified forever (
waitfor.exe /SI GetClipDone > nul
)

do forever
  ::
  :: Wait for the signal GetClipDone
  ::
  waitfor.exe GetClipDone > nul
  ::
  :: Remove monitor for e:\utils
  ::
  foldermonitor /c e:\utils
  ::
  :: Do some processing...
  ::
  echo Time from server.ini: %@iniread[.\server.ini,Main,theTime]
  ::
  :: Monitor the e:\utils\server.ini file for changes
  :: When triggered, send the signal GetClipDone
  ::
  foldermonitor e:\utils /i"server.ini" modified forever (
  waitfor.exe /SI GetClipDone > nul
  )
enddo
endlocal
:Done
foldermonitor /c e:\utils
quit

Once the above program is running, start up another TCC session, make a change in the file, switch back to the running .btm, and you should see the changes on the display.

Note that with this .btm running in TCC, when I make a change to the monitored file from a 16-bit program, a 32-bit program, or a 64-bit program, the file change is flagged in 64-bit TCC.

I used the techniques in the .BTM to allow me to make changes in a file from 4DOS running under vDosPlus.

Posting this mainly for my future reference, but thought others might also be interested.

Joe
 
May 20, 2008
10,670
83
Syracuse, NY, USA
WAITFOR is pretty cool, but what's the point of using it? This (FM.BTM) works by calling itself with a "trigger" option when a change occurs.

Code:
setlocal
on break goto done

:: this is triggered by FOLDERMONITOR ... process the change
if "%1" == "trigger" goto process_change

foldermonitor /c v:\

foldermonitor v:\ /i"test.txt" modified forever ( %0 trigger )

do forever ( delay 1 )

quit

:process_change
echo v:\test.txt was changed at %@filetime[v:\test.txt,w,s]
quit

:done
foldermonitor /c v:\
quit

One thing ... if I "echo foo > v:\test.txt" from another TCC, I get the FOLDERMONITOR command twice. Is that expected?

Code:
v:\> fm.btm
v:\test.txt was changed at 11:54:35
v:\test.txt was changed at 11:54:35
 
Not sure why you are getting it twice. I tested with your method, and also got the command twice.

Why would doing
Code:
echo foo > v:\test.txt
cause two successive triggers?

Using @INIWRITE I am only making a change to my file, not creating it, so I only get one trigger, as expected.

I changed your command to
Code:
echo %_folderaction & %0 trigger
which always returns MODIFIED.

Joe
 
Hey @vefatica I was originally trying to figure out how I could use MailSlots with TCC.

Since @FILEOPEN only works with Named Pipes, I looked for another method.

I discovered that WAITFOR.EXE is actually using a MailSlot, in my case \Device\Mailslot\WAITFOR.EXE\GetClipDone

I can programmatically create a Mailslot in 32-bit and 64-bit code, but WAITFOR.EXE was my TCC solution.

For example, this is a VBScript that will trigger WAITFOR.EXE in TCC

1591633570172.png


(This message board would not let me post the VBSCript as code, which is why it is an image)

Joe
 
May 20, 2008
10,670
83
Syracuse, NY, USA
If I change it to "echo foo >> v:\test.txt" (appending) I get only one modification. I imaging clobbering the file (and re-creating it?) involves an extra change to the timestamp. When I change my FOLDERMONITOR command to "%0 trigger %%_foldertime" and use ">" I get the likes of

Code:
v:\test.txt was changed at 12:28:48.566
v:\test.txt was changed at 12:28:48.582
 
May 20, 2008
10,670
83
Syracuse, NY, USA
If I change it to "echo foo >> v:\test.txt" (appending) I get only one modification. I imaging clobbering the file (and re-creating it?) involves an extra change to the timestamp. When I change my FOLDERMONITOR command to "%0 trigger %%_foldertime" and use ">" I get the likes of

Code:
v:\test.txt was changed at 12:28:48.566
v:\test.txt was changed at 12:28:48.582
Also had to change this.

Code:
:process_change
echo v:\test.txt was changed at %2
quit
 
May 20, 2008
10,670
83
Syracuse, NY, USA
You are only using the MODIFIED condition, which the help says

So, must be two of those items getting changed.

I think last write time is being changed twice ... because ...

I have a plugin WATCHDIR, much like FOLDERMONITOR. It has the following options for what to report.

Code:
/+...        filter list (see below); default: /+FDZW

  Filters (default: /+FDZW)

    F - filename (create, delete, rename)   Z - size
    D - dirname  (create, delete)           W - write time
    C - create time                         A - access time
    S - security                            T - attributes
    * - all of the above

When I use WATCHDIR with "/+W", ReadDirectoryChangesW gets ONLY the filter FILE_NOTIFY_CHANGE_LAST_WRITE (and none of the others that you mentioned). And in that case, it (like FOLDERMONITOR) is triggered twice when I redirect to a file with clobbering.

This might be interesting reading: ReadDirectoryChangesW
 
Aug 23, 2010
590
7
If you want to understand, what's going on, use processexplorer.
My bet is on the fact that you are watching directory changes, but expecting file changes.
When a file mtime is changed, in Windows, directory mtime is ALSO changed.
You get two notifications.