user3624406
user3624406

Reputation: 29

How to get the file name which just got modified using windows batch program

I am trying to solve a problem where I am monitoring a specific directory. My batch program monitors for the files that gets modified and records them in a txt file. So far I have written the code where it can detect when a file changes and can print a time stamp.

But now I also need it to record the name of the file that just got modified. Can anyone please help me with this. Here is what I have done so far:

@Echo Off
Set _Delay=10
Set _Monitor=C:\Users\MMurshed\Desktop\New folder (3)
Set _Base=%temp%\BaselineState.dir
Set _Chck=%temp%\ChkState.dir
Set _OS=6
Ver|Findstr /I /C:"Version 5">Nul
If %Errorlevel%==0 Set _OS=5 & Set /A _Delay=_Delay*1000
:_StartMon
Call :_SetBaseline "%_Base%" "%_Monitor%"
:_MonLoop
If %_OS%==5 (Ping 1.0.0.0 -n 1 -w %_Delay%>Nul) Else Timeout %_Delay%>Nul
Call :_SetBaseline "%_Chck%" "%_Monitor%"
FC /A /L "%_Base%" "%_Chck%">Nul
If %ErrorLevel%==0 Goto _MonLoop
::
:: Insert code to run when a change occurs
::
Echo.Change Detected
Echo.Timestamp = %date:~0,2%%date:~3,2%%date:~6,8%-%time:~0,2%%time:~3,2%%time:~6,2%


Goto :_StartMon
:::::::::::::::::::::::::::::::::::::::::::::::::::
:: Subroutine
:::::::::::::::::::::::::::::::::::::::::::::::::::
:_SetBaseline
If Exist "%temp%\tempfmstate.dir" Del "%temp%\tempfmstate.dir"
For /F "Tokens=* Delims=" %%I In ('Dir /S "%~2"') Do (
Set _Last=%%I
>>"%temp%\tempfmstate.dir" Echo.%%I
)
>"%~1" Findstr /V /C:"%_Last%" "%temp%\tempfmstate.dir"
Goto :EOF

Upvotes: 1

Views: 102

Answers (2)

woxxom
woxxom

Reputation: 73726

Access WMI from a VBScript code embedded in the batch file to monitor directory changes and do what you need inside this code (currently it prints the info to console):

@echo off
set "vbsfile=%temp%\dirwatch%random%.vbs"
>"%vbsfile%" (
    for /f "delims=: tokens=* eol=" %%a in ('findstr /b ":::" "%~dpnx0"') do echo.%%a
)
cscript //nologo "%vbsfile%"
del "%vbsfile%"
exit /b

:::intInterval = "10"
:::strDrive = "c:"
:::strFolder = replace("\Users\MMurshed\Desktop\New folder (3)", "\", "\\")
:::strComputer = "."
:::
:::Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\" &_
::: strComputer & "\root\cimv2" )
:::
:::Set events = objWMIService.ExecNotificationQuery( _
::: "Select * From __InstanceOperationEvent" _
::: & " Within " & intInterval _
::: & " Where Targetinstance Isa 'CIM_DataFile'" _
::: & " And TargetInstance.Drive='" & strDrive & "'"_
::: & " And TargetInstance.Path='" & strFolder & "'")
:::
:::Do
::: Set fileEvent = events.NextEvent()
::: Set fileInfo = fileEvent.TargetInstance
:::
::: Select Case fileEvent.Path_.Class
:::     Case "__InstanceCreationEvent"
:::         WScript.Echo "Created: " & fileInfo.Name
:::     Case "__InstanceDeletionEvent"
:::         WScript.Echo "Deleted: " & fileInfo.Name
:::     Case "__InstanceModificationEvent"
:::         Set prevFile = fileEvent.PreviousInstance
:::         For Each prop In fileInfo.Properties_
:::             If prop.Value <> prevFile.Properties_(prop.Name) Then
:::                 WScript.Echo "Changed:        " & fileInfo.Name
:::                 WScript.Echo "Property:       " & prop.Name
:::                 WScript.Echo "Previous value: " & prevFile.Properties_(prop.Name)
:::                 WScript.Echo "New value:      " & prop.Value
:::                 WScript.Echo
:::             End If
:::         Next
::: End Select
:::Loop

P.S. Due to quota restrictions of WMI service the subfolders aren't monitored

The code is taken from WMI and File System Monitoring article by Uros Calakovic.

Upvotes: 1

Stephan
Stephan

Reputation: 56208

you can use the Archive Attribut to check for new or changed files (that's what it's supposed to be used to)

Windows sets this Attribute every time, a file is created or changed, so just ask Windows for "changed files" :)

@echo off
rem create some files
echo hello>a.txt
echo hello>b.txt
echo hello>c.txt
call :check
echo marking them by settting the "Archive" attribute:
attrib -a *.txt
call :check
echo changing a file
echo world>>b.txt
call :check
attrib -a *.txt
goto :eof

:check
echo ========================
echo new or changed files:
dir /b /aa-d *.txt
echo ------------------------
echo unchanged files:
dir /b /a-a-d *.txt
echo ========================
goto :eof

Upvotes: 0

Related Questions