monitor last modified time for a folder using batch file - batch-file

I have a folder on my workstation where files are added every minute.
I have to monitor this folder every now and then, to see if new files are being added.
In case there is no new file in this folder for say 5 min, we perform an action.
Can we use batch file for this purpose in such a way that if there is no new file added for last 5 min, an alert /pop up apears on window screen.
Also I m new to Batch .Please let me know the steps

It seems unlikely that you are going to accomplish what you want to do with purely a batch file.
However, you can do this in a relatively simple/small VB Script, that doesn't require any additional installation on the system.
'-------------------------------------------------------------
' Monitors a folder for new files and warns if they
' are not being created within a certain time period.
'-------------------------------------------------------------
Dim intMinutes: intMinutes = 5 ' minute threshold for warning of no new files
Dim strDrive: strDrive = "c:" ' drive to monitor
Dim strPath: strPath = "\\temp\\" ' path to monitor. remember to double slashes
Dim intTimer: intTimer = "2"
Dim strComputer: strComputer = "."
Dim objWMIService: Set objWMIService = GetObject( "winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2" )
Dim strQuery: strQuery = "Select * From __InstanceOperationEvent" & " Within " & intTimer & " Where Targetinstance Isa 'CIM_DataFile'" & " And TargetInstance.Drive='" & strDrive & "'" & " And TargetInstance.Path='" & strPath & "'"
Dim colEvents: Set colEvents = objWMIService. ExecNotificationQuery (strQuery)
Dim LastNew: LastNew = Now
WScript.Echo "Monitoring new file creation... Press [Ctrl]-[C] to exit"
Do
Set objEvent = colEvents.NextEvent()
Set objTargetInst = objEvent.TargetInstance
Select Case objEvent.Path_.Class
Case "__InstanceCreationEvent"
LastNew = Now
End Select
if DateDiff("n",LastNew,Now) >= intMinutes then
' put whatever actions you want in here... the following two lines are for demo purposes only
msgbox "The last new file was " & DateDiff("n",LastNew,Now) & " minute ago!",0,"No New Files"
exit do
end if
Loop
Execute this in WScript to make it not visible or CScript to show the console window.
Replace the code inside the IF block to do what you need done (notify you of the issue).

Related

VBS to Rename File via Send To Menu

Every day I have to rename files to replace spaces with dashes before I can send them to our machines (a few of our machines don't read spaces in file names but our file naming conventions have spaces, a conflict of interest I know).
Sometimes it's one file others it's a half dozen so my approach is to use the Windows Send To menu to send selected files to the script.
I've gotten as far as renaming the strings but the actual move function says path not found when I get to the fso.movefile function.
Here's what I have so far.
Set objArgs = WScript.Arguments
Dim Fso
Set Fso = WScript.CreateObject("Scripting.FileSystemObject")
'Cycle through files
For I = 0 to objArgs.Count - 1
' Assign array entry to variable
t = objArgs(I)
' Parse variable to replace spaces with dashes
s = Replace(t, " ", "-")
' Let me know how I did
WScript.Echo t & vbcrlf & s
'Move 'em
fso.movefile t, s
Next
Any help will be greatly appreciated.
So my problem was the folder I was in had spaces too. So my code was trying to rename to a folder that didn't exist.
Once I parsed the file name out of the path and re-grouped the modified file name it worked great. Code below.
Dim t ' original file and path
Dim s ' file name only with spaces
Dim u ' new file name without spaces
Dim v ' path only
Dim obj
Set objArgs = WScript.Arguments
set obj = WScript.CreateObject("Scripting.FileSystemObject")
'Cycle through files
For I = 0 to objArgs.Count - 1
' Assign array entry to variable
t = objArgs(I)
' Parse file name from path
s = Right(t, Len(t) - InStrRev(t, "\"))
' Remove file name from path
v = left(t, InStrRev(t, "\"))
' Parse variable to replace spaces with dashes
u = Replace(s, " ", "-")
' ' Let me know how I did
' WScript.Echo "Was(t): " & t & vbcrlf & "Is(s): " & s & vbcrlf & "Path: " & v
'Move 'em
obj.movefile t, v & u
Next

Windows batch script spawn normal windows copy process

Im writing a batch script to help me collect some bandwidth data about numerous offices on our WAN. It uses random data file creator to help me avoid wan optimisers affecting the results.
How can I copy a file by spawning a standard windows copy window that shows transfer rate?
If i use the 'copy' method, it just copies silently in the cmd window and i cant see the rate.
if not exist "C:\temp\xfertest" mkdir C:\test\xfertest
rdfc C:\test\xfertest\random100.dat 100000000
copy C:\test\xfertest\random100.dat \\nat-srv-007\Deliver
exit
This vbscript wrappped in a batch file will do what you want. Save it with a .bat/.cmd extension. Or without the first line with a .vbs extension.
The technic used is based on com and works with every script language supporting it.
Just to see start/end date time, total bytes and bytes per/s it outputs these values to the console after the copy dialog window has vanished.
rem^ &#cscript //nologo //e:vbscript "%~f0" %* & exit /b
' Copy with the windows dialog box
Option Explicit
Dim cArgs : Set cArgs = WScript.Arguments
Dim iArgCnt : iArgCnt = cArgs.Count
Dim sSource : sSource = cArgs.Item(0)
Dim sDest : sDest = cArgs.Item(1)
Dim oFS : Set oFS = CreateObject("Scripting.FileSystemObject")
Dim oSH : Set oSH = CreateObject("shell.application")
Dim oFile, Size, dStart, dEnd
If iArgCnt <> 2 Then
Wscript.Echo "Wrong args, need SourceFile and DestFolder"
Wscript.Quit
End if
If oFS.FileExists(sSource) Then
Set oFile = oFS.GetFile(sSource)
Size = oFile.Size
If oFS.FolderExists(sDest) Then
dStart = Now()
Wscript.Echo "Copy : " & sSource & " " & sDest
Wscript.Echo "Start: " & dStart & " Size : " & Size
FolderCopyHere sSource, sDest
dEnd = Now()
Wscript.Echo "End : " & dEnd & " per/s: " & _
Int(Size / DateDiff("s", dStart, dEnd))
Else
Wscript.Echo "Destination Folder doesn't exist" & sDest
End if
Else
Wscript.Echo "Source file doesn't exist" & sSource
End if
Wscript.Quit
function FolderCopyHere(sSource,sDest)
dim oFld
set oFld = oSH.NameSpace(sDest)
if not oFld is nothing then
oFld.CopyHere(sSource)
end if
set oFld = nothing
end function
Returning this output on my pc
20:28:24 C:\Test________________________________________
> k:\Bat\CopyExpl.cmd c:\test\big.file Q:\Test
20:28:36 C:\Test________________________________________
> rem &
Copy : c:\test\big.file Q:\Test
Start: 2016-10-30 20:28:36 Size : 2147483648
End : 2016-10-30 20:29:10 per/s: 63161283
20:29:10 C:\Test________________________________________
The Rem stems from the wrapper the dialog box is widely known. HTH

Convert Access Attachment data type to file system files

I have a lot of files stored as attached files in an Access db. I am going to move data to an SQL server and for that purpose I need to extract the attached files and turn them into file system files.
This snippet works fine for images and pdf files but not for Office documents like Word or Excel. I assume it has something to do with encoding, but I have no clues. Any ideas?
Dim dbs As Database
Dim rs As Recordset
Set dbs = CurrentDb
Set rs = dbs.OpenRecordset("table1")
With rs
Do While Not .EOF
Set rsRec = rs.Fields("AttFiles").Value
While Not rsRec.EOF
NameOfFile = "C:\temp\" & rsFil.Fields("FileName")
Open NameOfFile For Binary Access Write As #1
Put #1, , rsRec.Fields("FileData").Value
Close #1
rsRec.MoveNext
Wend
.MoveNext
Loop
End With
rs.Close
dbs.Close
If the File is actually an attachment type, then you might as well use the Recordset2 of the Microsoft Access Object Library. Something like,
Public Sub exportDocument(tableName As String, fieldName As String, uniqueID As Long)
On Error GoTo Err_SaveImage
Dim rsParent As DAO.Recordset2
Dim rsChild As DAO.Recordset2
Dim saveAsName As String
Set rsParent = CurrentDb.OpenRecordset("SELECT " & tableName & ".* " & _
"FROM " & tableName & " WHERE " & tableName & "." & fieldName & " = " & uniqueID)
Set rsChild = rsParent.Fields("fileData").Value
If rsChild.RecordCount <> 0 Then
If Dir(Environ("userprofile") & "\My Documents\tmp\", vbDirectory) <> "." Then MkDir Environ("userprofile") & "\My Documents\tmp\"
saveAsName = Environ("userprofile") & "\My Documents\tmp\" & rsChild.Fields("FileName")
rsChild.Fields("fileData").SaveToFile saveAsName
FollowHyperlink saveAsName
End If
Exit_SaveImage:
Set rsChild = Nothing
Set rsParent = Nothing
Exit Sub
Err_SaveImage:
If Err = 3839 Then
Resume Next
Else
MsgBox "Some Other Error occured!" & vbCrLf & vbCrLf & Err.Number & " - " & Err.Description, vbCritical
Resume Exit_SaveImage
End If
End Sub
The above code will save the files to a location specified in saveAsName. I have specific unique ID in the WHERE condition. If you want to export all documents, you can alter the code accordingly, but might have to loop through the recordset. I hope this helps !

vbscript: Constantly check if file(s) exists and display life-time

I got a very specific question regarding my code.
So I got a folder. In this folder there can be >=0 files.
My first script is running in the background, checking if file-count is >0.
As soon as it is >0, it activates a second script with the path+filename, and as soon as
a file is deleted/removed from the folder, it displays the lifetime of the file.
Everything works fine, but there is one problem:
If there are multiple Files in the folder simultaniously, it only "observers" the top one (filename,ascending). So if the first one gets deleted, it sure does observe the second, but the lifetime is wrong because it did not start until the first one got deleted.
Here are my two codes:
Script1.vbs:
Set fso =CreateObject("Scripting.FileSystemObject")
If WScript.Arguments.Count = 1 Then
pfadTiff0 = CStr(WScript.Arguments(0))
Else
msgbox "Bitte Argumente (Pfade) angeben"
WScript.Quit
End If
While True
Set ordnerTiff0 = fso.GetFolder(pfadTiff0)
Set filesTiff0 = ordnerTiff0.Files
anzFilesTiff0 = ordnerTiff0.Files.Count
If anzFilesTiff0 > 0 Then
For Each objFile in filesTiff0
CreateObject("WScript.Shell").Run "QueueTimeUP.vbs " & objFile.Name & " " & pfadTiff0, 0, True
Next
End If
WScript.Sleep 2000
WEnd
Script2.vbs:
filename = CStr(WScript.Arguments(0))
pfad = CStr(WScript.Arguments(1))
Set fso = CreateObject("Scripting.FileSystemObject")
startZeit = Timer()
komplett = pfad&"\"&filename
While fso.FileExists(komplett) = True
WScript.Sleep 100
WEnd
endZeit = Timer()
differenz = endZeit-startZeit
msgbox "Existenz von Job " & filename & " in Sekunden: " & differenz
Thanks for your help guys.
#Bond: Removing the while true loop is no option, since the program is not allowed to stop running. Even if there are no files at this time, there will always be new files later which have to be observed too. But your hint with the "false" parameter of the Run-Statement was great!
#Rob1991:
Good idea, that was actually my first idea before I put my question here.
I figured it out by myself with a different solution. Maybe it helps anybody:
Set fso =CreateObject("Scripting.FileSystemObject")
If WScript.Arguments.Count = 1 Then
pfadTiff0 = CStr(WScript.Arguments(0))
Else
msgbox "Bitte Argumente (Pfade) angeben"
WScript.Quit
End If
Set ordnerTiff0 = fso.GetFolder(pfadTiff0
Set filesTiff0 = ordnerTiff0.Files
letztesFile = "000a" // PART OF SOLUTION, IT´S "LAST FILE"
While True
For Each objFile in filesTiff0
If objFile.Name > letztesFile Then // PART OF SOLUTION
CreateObject("WScript.Shell").Run "QueueTimeUP.vbs " & objFile.Name & " " & pfadTiff0, 0, False // thanks Bond for "false"
letztesFile = objFile.Name // PART OF SOLUTION
End If
Next
WScript.Sleep 500
WEnd
This statement:
CreateObject("WScript.Shell").Run "QueueTimeUP.vbs " & objFile.Name & " " & pfadTiff0, 0, True
Uses a value of True as the last parameter. That specifies that you want to wait until the script completes (synchronous) before returning. So your main script is put in a wait state until your second script (QueueTimeUp.vbs) exits, which doesn't happen until the first file is deleted.
You should be able to use False as the last param, which doesn't wait for the second script to complete. Then remove your While True loop and just allow your main script to complete.
' Main script. Remove "While True" loop.
Set ordnerTiff0 = fso.GetFolder(pfadTiff0)
Set filesTiff0 = ordnerTiff0.Files
anzFilesTiff0 = ordnerTiff0.Files.Count
If anzFilesTiff0 > 0 Then
For Each objFile in filesTiff0
' Use False for last param to specify asynchronous call...
CreateObject("WScript.Shell").Run "QueueTimeUP.vbs " & objFile.Name & " " & pfadTiff0, 0, False
Next
End If
' Allow script to complete.
Now you'll have a QueueTimeUp.vbs script running for each file in your folder.
FYI: If you're familiar with scripting WMI via VBScript, it provides the __InstanceCreationEvent and __InstanceDeletionEvent classes that can notify your script when a file is created or deleted, respectively. Then you won't have to poll a folder every few seconds looking for changes.
I believe for each file it will load the vbs2, but will not start the next execution until vbs2 has ended. If i used the following code below it will not iterate until the instance of cmd has been ended
For Each objFile in colFiles
oShell.run "cmd /k CD C:\Program File" ,1 , true
Next
I think you would want to have a start timer in your first vbs, and then pipe it to the second vbs2. Which would mean the start time is only called once at the start of the programs execution
startZeit = Timer()
For Each objFile in filesTiff0
CreateObject("WScript.Shell").Run "QueueTimeUP.vbs " & objFile.Name & " " & pfadTiff0 & " " & startZeit , 0, True
Next
vbs 2
startZeit = CStr(WScript.Arguments(2))
Hope this helps

How to set parameters in a batch file equal to a VB6 variable

In my batch file, I am calling a VBScript and passing it 3 parameters. The parameters are "IPADDRESS" "PicName" and "Storage", as seen below:
Batch File:
set Pathname="C:\User\username\locationOfFile
cd /d %Pathname%
cscript.exe C:\User\username\locationOfFile\myScript.vbs IPADDRESS PicName Storage
In my VB6 program, the parameter values are defined.
Lets say for instance IPADDRESS = "170.190.xxx.xxx"
Is there a way I can have the batch file read and use the value of IPADDRESS based off the declaration inside the VB6 form? The variables IPADDRESS, PicName, and Storage will be constantly changing based off an outside application the VB6 program talks to so I cant statically set it up in the batch ( ....\myScript.vbs 170.190.xxx.xxx pic1 C:\Storage)
My VBScript is given below:
Option explicit
if WScript.Arguments.Count <> 3 then
WScript.Echo "Missing parameters"
else
Dim imageMagick
Set imageMagick = CreateObject("ImageMagickObject.MagickImage.1")
Dim cam_add
Dim annotate
Dim filename
Dim cmd
Dim WshShell
Dim return
cam_add = """http://" & WScript.Arguments(0) &"/image"""
annotate = """" & WScript.Arguments(1) & " - """ '& Date
filename = """" & WScript.Arguments(2) & WScript.Arguments(1) & ".jpg"""
cmd = "convert " & cam_add & " -fill gold -pointsize 45 -gravity southwest -annotate 0x0+25+25 " & annotate & " -trim +repage -verbose " & filename
WScript.Echo cmd
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.CurrentDirectory = "C:\Program Files\ImageMagick-6.8.0-Q16\"
return = WshShell.Run(cmd)
end if
In summation, I need to to have the batch set up like:
cscript.exe C:\User\username\locationOfFile\myScript.vbs IPADDRESS PicName Storage
so the parameter values can used according to what they are set to inside my VB6 form.
If you were to:
shell "the.bat " & IPADDRESS & " " & PicName & " " & Storage
then within the.bat each space delimited argument is available via %N where N is the ordinal number; so %1 would contain the value of IPADDRESS, %2 would contain PicName's value and so on.
To then forward to the VBScript:
cscript.exe C:\User\username\locationOfFile\myScript.vbs %1 %2 %3
(If any of the variables contain spaces, you will need to "quote" them before passing to the bat file)
(You could also probably just chdir(..) in VB6 then run CScript directly)
For something this simple there is no need for a batch file anyway. After all, you have a whole script to work with.
You can even set the CD from inside there, or set it in the VB6 program as here:
Option Explicit
Private Sub Main()
Dim CD As String
Dim IPADDRESS As String
Dim PicName As String
Dim Storage As String
Dim OrigCD As String
CD = "D:\Photo Archives"
IPADDRESS = "127.0.0.1"
PicName = "Fudd"
Storage = "C:\Storage"
'Cache CD so we can restore it.
'Change CD and drive so it is inherited.
OrigCD = CurDir$()
ChDir CD
ChDrive CD
Shell "cscript """ _
& App.Path & "\test.vbs "" """ _
& IPADDRESS & """ """ _
& PicName & """ """ _
& Storage & """", _
vbNormalFocus
'Restore CD and drive.
ChDir OrigCD
ChDrive OrigCD
'Rest of program.
End Sub
Script sample:
Option Explicit
Private CD
Private Sub Msg(ByVal Text)
With WScript
.StdOut.WriteLine Text
.StdOut.Write "Press ENTER to continue..."
.StdIn.ReadLine
End With
End Sub
If WScript.Arguments.Count <> 3 Then
Msg "Missing parameters"
WScript.Quit
End If
'Show the CD and the arguments.
With CreateObject("WScript.Shell")
CD = .CurrentDirectory
End With
With WScript.Arguments
Msg CD & vbNewLine _
& """" & .Item(0) _
& """ """ & .Item(1) _
& """ """ & .Item(2) & """"
End With
But it doesn't even look like the script is needed. You can build the command, set the CD/drive, and Shell() the built command string all from inside the VB6 program.

Resources