Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

check multiple files 1

Status
Not open for further replies.

sugram

Technical User
Feb 5, 2021
26
0
0
DE
Hello

I would like to check several files whether they have been changed.
I have already found a VBS code via google, it also works perfectly with a single file.
But unfortunately I don't know how to use it to check multiple files.

I wanted to try this in batch, but unfortunately without success

Batch Code:
Code:
dir /b c:\tmp\*.cfg >> C:\temp\CFG.txt
for /f  %%i in (C:\temp\CFG.txt) do cscript C:\batch\CFG.vbs c:\tmp\%%i

VBS CODE:
Code:
param = WScript.arguments.item(0)
sFile = "& param"
lInterv = 3000'30 s

If WScript.Arguments.Count > 0 Then sFile = WScript.Arguments(0)
If WScript.Arguments.Count > 1 Then lInterv = WScript.Arguments(1)
'MsgBox "Ueberwachung von " & sFile & vbCrLF & "gestartet, Intervall: " & lInterv / 1000 & " Sekunden"
Set fso = CreateObject("Scripting.FileSystemObject")
bRun = True
sTimeStamp = fso.GetFile(sFile).DateLastModified
Do While bRun
	Do While fso.GetFile(sFile).DateLastModified = sTimeStamp
		WScript.Sleep lInterv
	Loop
	sTimeStamp = fso.GetFile(sFile).DateLastModified
	iRet = MsgBox("Datei " & sFile & " wurde geaendert." , 65, sTimeStamp)
	If iRet = vbCancel Then bRun = False
Loop

I hope that someone here can help me.
Many Thanks
 
What exactly would you like to do?
Code:
    for each file
        sleep a bit
        get the last modified date until the user presses cancel
or
Code:
    loop
        find last modified date of each file until user presses cancel

or something else.
 
Hello

Thanks for the Answer.

I want to check certain files to see whether they have been changed and a message window will appear.
The VBS-Script already does this with a single file.
Now I am missing that it works with several files.

I think i need this:
Code:
loop
        find last modified date of each file until user presses cancel
 
sugram said:
...
But unfortunately I don't know how to use it to check multiple files.
...
I wanted to try this in batch, but unfortunately without success
Running the VBscript from batch, like you tried seems not to good, because it would run the VBscript with the first file then with the second and so on.
But you need to run the VBscript on all files at the same time. Maybe, it could be possible to run the monitoring on every file in a separate job, but then how to stop monitoring of all files at the same time? I thought about this but IMHO it seems to be not so simple ...

In my opinion, the easiest way is to adapt the existing script, like this:
1) Read a config file with the file names which should be monitored, store them and their timestamps into a dictionary (with key = FileName and Value = TimeStamp)
2) In the sleep loop iterate over all monitored files and if nothing changed sleep for n milliseconds
3) After exiting the sleep loop, i.e. when some of the files changed, iterate over all monitored files and print info about those which changed.
4) Replace MsgBox with wscript.echo, because we don't want to press OK or Cancel after every file changed, it's better to write changes on command line window, where we could redirect the output into a log file.
 
First I created a config file which contains all files to be monitored, for example like this:

sugram.cfg
Code:
c:\tmp\sugram_01.txt
c:\tmp\sugram_02.txt
c:\tmp\sugram_03.txt
then I store the file names with their timestamps into dictionary, so I can iterate over the dictionary and check if something changed, when a file timestamp changes, I have to update it's dictionary entry

And here is your modified script, try it how it works:

sugram.vbs
Code:
[COLOR=#0000ff]' run:[/color]
[COLOR=#0000ff]'   cscript /NoLogo sugram.vbs [milliseconds][/color]

configFileName [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]"c:\tmp\sugram.cfg"[/color]

lInterv [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]3000[/color][COLOR=#0000ff] '3 s[/color]

[COLOR=#0000ff]'dictionary: key = FileName, value = FileTimeStamp[/color]
[COLOR=#804040][b]set[/b][/color] fileDic [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]CreateObject[/color][COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]"Scripting.Dictionary"[/color][COLOR=#804040][b])[/b][/color]
[COLOR=#804040][b]call[/b][/color] populateFileDic[COLOR=#804040][b]([/b][/color]configFileName[COLOR=#804040][b],[/b][/color] fileDic[COLOR=#804040][b])[/b][/color]

[COLOR=#804040][b]If[/b][/color] WScript[COLOR=#804040][b].[/b][/color]Arguments[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]Count[/color] [COLOR=#804040][b]>[/b][/color] [COLOR=#ff00ff]0[/color] [COLOR=#804040][b]Then[/b][/color] lInterv [COLOR=#804040][b]=[/b][/color] WScript[COLOR=#804040][b].[/b][/color]Arguments[COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]0[/color][COLOR=#804040][b])[/b][/color]

[COLOR=#a020f0]keys[/color] [COLOR=#804040][b]=[/b][/color] fileDic[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]keys[/color]
wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]"Starting to monitor following files"[/color][COLOR=#804040][b] _[/b][/color]
  [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]" in interval of "[/color] [COLOR=#804040][b]&[/b][/color] lInterv [COLOR=#804040][b]/[/b][/color] [COLOR=#ff00ff]1000[/color] [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]" seconds:"[/color]
[COLOR=#804040][b]for[/b][/color] i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color] [COLOR=#804040][b]to[/b][/color] fileDic[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]count[/color][COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]1[/color]
  sFile [COLOR=#804040][b]=[/b][/color]  [COLOR=#a020f0]keys[/color][COLOR=#804040][b]([/b][/color]i[COLOR=#804040][b])[/b][/color]
  wscript[COLOR=#804040][b].[/b][/color]echo [COLOR=#ff00ff]vbTab[/color] [COLOR=#804040][b]&[/b][/color] sFile
[COLOR=#804040][b]next[/b][/color]
[COLOR=#804040][b]Set[/b][/color] fso [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]CreateObject[/color][COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]"Scripting.FileSystemObject"[/color][COLOR=#804040][b])[/b][/color]
bRun [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]True[/color]
[COLOR=#804040][b]Do[/b][/color] [COLOR=#804040][b]While[/b][/color] bRun
  nothingChanged [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]True[/color]
  [COLOR=#804040][b]Do[/b][/color] [COLOR=#804040][b]While[/b][/color] nothingChanged
    [COLOR=#804040][b]for[/b][/color] i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color] [COLOR=#804040][b]to[/b][/color] fileDic[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]count[/color][COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]1[/color]
      sFile [COLOR=#804040][b]=[/b][/color]  [COLOR=#a020f0]keys[/color][COLOR=#804040][b]([/b][/color]i[COLOR=#804040][b])[/b][/color]
      sTimeStamp [COLOR=#804040][b]=[/b][/color] fileDic[COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b])[/b][/color]
      nothingChanged [COLOR=#804040][b]=[/b][/color] nothingChanged[COLOR=#804040][b] _[/b][/color]
                       [COLOR=#804040][b]and[/b][/color] [COLOR=#804040][b]([/b][/color]fso[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]GetFile[/color][COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b]).[/b][/color]DateLastModified [COLOR=#804040][b]=[/b][/color] sTimeStamp[COLOR=#804040][b])[/b][/color]
    [COLOR=#804040][b]next[/b][/color]
    WScript[COLOR=#804040][b].[/b][/color]Sleep lInterv
  [COLOR=#804040][b]Loop[/b][/color]

  [COLOR=#804040][b]for[/b][/color] i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color] [COLOR=#804040][b]to[/b][/color] fileDic[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]count[/color][COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]1[/color]
     sFile [COLOR=#804040][b]=[/b][/color]  [COLOR=#a020f0]keys[/color][COLOR=#804040][b]([/b][/color]i[COLOR=#804040][b])[/b][/color]
     sTimeStamp [COLOR=#804040][b]=[/b][/color] fileDic[COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b])[/b][/color]
     dateLastModified [COLOR=#804040][b]=[/b][/color] fso[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]GetFile[/color][COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b]).[/b][/color]DateLastModified
     [COLOR=#804040][b]if[/b][/color] sTimeStamp [COLOR=#804040][b]<>[/b][/color] dateLastModified [COLOR=#804040][b]then[/b][/color]
      [COLOR=#0000ff] ' change dictionary value[/color]
       fileDic[COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b])[/b][/color] [COLOR=#804040][b]=[/b][/color] dateLastModified
       wscript[COLOR=#804040][b].[/b][/color]echo dateLastModified [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]" changed: "[/color] [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]vbTab[/color][COLOR=#804040][b] _[/b][/color]
         [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]""""[/color]  [COLOR=#804040][b]&[/b][/color] sFile [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]""""[/color][COLOR=#804040][b] _[/b][/color]
         [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]vbTab[/color] [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]vbTab[/color] [COLOR=#804040][b]&[/b][/color] [COLOR=#ff00ff]"timestamp before: "[/color] [COLOR=#804040][b]&[/b][/color] sTimeStamp
     [COLOR=#804040][b]end[/b][/color] [COLOR=#804040][b]if[/b][/color]
  [COLOR=#804040][b]next[/b][/color]
[COLOR=#804040][b]Loop[/b][/color]

[COLOR=#804040][b]sub[/b][/color] populateFileDic[COLOR=#804040][b]([/b][/color]configFileName[COLOR=#804040][b],[/b][/color] fileDic[COLOR=#804040][b])[/b][/color]
 [COLOR=#0000ff] ' populates file dictionary from config file[/color]
  [COLOR=#804040][b]set[/b][/color] fso [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]CreateObject[/color][COLOR=#804040][b]([/b][/color][COLOR=#ff00ff]"Scripting.FileSystemObject"[/color][COLOR=#804040][b])[/b][/color]
  [COLOR=#804040][b]set[/b][/color] configFile [COLOR=#804040][b]=[/b][/color] fso[COLOR=#804040][b].[/b][/color]OpenTextFile[COLOR=#804040][b]([/b][/color]configFileName[COLOR=#804040][b])[/b][/color]
  [COLOR=#804040][b]do[/b][/color] [COLOR=#804040][b]while[/b][/color] [COLOR=#804040][b]not[/b][/color] configFile[COLOR=#804040][b].[/b][/color]AtEndOfStream
    sFile [COLOR=#804040][b]=[/b][/color] configFile[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]ReadLine[/color][COLOR=#804040][b]()[/b][/color]
    sTimeStamp [COLOR=#804040][b]=[/b][/color] fso[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]GetFile[/color][COLOR=#804040][b]([/b][/color]sFile[COLOR=#804040][b]).[/b][/color]DateLastModified
   [COLOR=#0000ff] ' add to dictionary[/color]
    fileDic[COLOR=#804040][b].[/b][/color][COLOR=#a020f0]add[/color] sFile[COLOR=#804040][b],[/b][/color] sTimeStamp
  [COLOR=#804040][b]loop[/b][/color]
 [COLOR=#0000ff] 'close the input file[/color]
  configFile[COLOR=#804040][b].[/b][/color][COLOR=#804040][b]close[/b][/color]
[COLOR=#804040][b]end[/b][/color] [COLOR=#804040][b]sub[/b][/color]

 
If you were using VB6 or VBA, I'd point you at some of my code in the VB6 forum whoich leverages the fact that NTFS can actually send you notifications if a file changes. Sadly you can't use this in VBScript, because you can't make the necessary API calls. However .NET wrapped all that up in a class called FileSystemWatcher - which you can access in Powershell - and it sounds to me like that might be something you might want to investigate, as it is far simpler (well, apart from learning PowerShell) than jumping through pure VBscript alternatives.
 
mikrom said:
And here is your modified script, try it how it works:

The Script Works great :)

Many Thanks!!

strongm said:
If you were using VB6 or VBA, .....

yes, I've already found something about Powershell, but I have to leran it first.
Thank you very much for the hint
 
sugram said:
I've already found something about Powershell, but I have to learn it first.

After you have been prepared for PowerShell, you can post your question in our PowerShell forum - here: Maybe strongm will then provide an example with the FileSystemWatcher class. In my opinion, it would be interesting to compare these two approaches.
 
I'm happy to share an illustrative version here just so the OP can see what they might be letting themselves in for (and note I'm not really a Powershell programmer)

Code:
[blue]$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'D:\downloads\WatchMe'
$watcher.EnableRaisingEvents = $true
$files = 'test.txt','test2.txt'
Write-Host Starting to monitor $files
Register-ObjectEvent $watcher 'Changed' -Action $action | out-null

$action =
{
    if ($files.contains($event.SourceEventArgs.name))
    {
        $path = $event.SourceEventArgs.FullPath
        $changetype = $event.SourceEventArgs.ChangeType
        Write-Host "$path was $changetype at $(get-date)"
    }
}
[COLOR=green]#Get-EventSubscriber | Unregister-Event[/color][/blue]
 
strongm , thank you very much for posting this example.
When I look at it, I can't take it and I have to say it: Oh my god, the PowerShell programming language looks like it's a child of COBOL and Perl. It looks like all serious programming languages use hyphens - like COBOL :)
 
Hello

@strongm Many Thanks.

I tested your script, but it doesn't work for me.
I always land on the console and it doesn't do anything

after googling and testing the weekend, i have this powershell script so far.
Code:
Add-Type -AssemblyName PresentationFramework
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "c:\tmp\tk"
$watcher.Filter = "*.cfg"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$null = Register-ObjectEvent $watcher "Changed" -Action {Send-MailMessage –To "Email.Adress@domain.com" –Subject "CFG DATEI GEÄNDERT!" –Body "CFG Datei wurde geändert!" –SmtpServer "smtp.com" –From "noreplay@domain.com" -encoding ([System.Text.Encoding]::UTF8)}
while ($true) {sleep 10}

it works, only I always get two email's.
But i don't understand why

Can you tell me why?
And how can I query multiple paths ?!
Because I would like to be able to query several PCs

And when i edit the script to open a Picture, i get multiple E-Mails
Code:
Add-Type -AssemblyName PresentationFramework
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "c:\tmp\tk"
$watcher.Filter = "*.cfg"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
$null = Register-ObjectEvent $watcher "Changed" -Action {Send-MailMessage –To "Email.Adress@domain.com" –Subject "CFG DATEI GEÄNDERT!" –Body "CFG Datei wurde geändert!" –SmtpServer "smtp.com" –From "noreplay@domain.com" -encoding ([System.Text.Encoding]::UTF8)}
$null = Register-ObjectEvent $watcher "Changed" -Action {Invoke-Item "C:\Users\username\Documents\test.jpg"}
while ($true) {sleep 10}

Many Thanks
 
Yep, should have said - my Powershell code was designed to work from the Integrated Scripting Environment (i.e Powershell ISE), which obviates the need for the sleep loop that you have come up with

>I always get two email's.

Very much depends on what is modifying the file. Some applications cause multiple change events when changing a file


Anyway, you are definitely moving into the realms of asking questions about PowerShell, and they should definitely be taken to forum1619, as previously advised by mikrom
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top