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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File Watcher to Copy and Append File Name 1

Status
Not open for further replies.

Nu2Java

Technical User
Jun 5, 2012
166
US
Hello, I have a script here that I am using (with the help of the great people here on Tek-Tips). What I have now works good for me, but what I would like to do is watch the file for change, then copy the file out, just like I am doing in this script. The problem is, I want to copy the file and save a different copy of the file each time it is saved. How can I do this?

I will use this for an Excel file actually. I then want to create maybe 10 copies of the file in the directory and then purge out the older ones once they reach greater than 10. Any simple ideas?

Thanks for your help, as always.

Code:
dim filesys, objfolder, strdir
 set filesys=CreateObject("Scripting.FileSystemObject")
 
strdir = "C:\temp\test\"
 
'If filesys.FolderExists(strdir) Then
 'filesys.CopyFile "C:\test\test.txt", strdir, True



strComputer = "."
strDrive = "C:"
strFolder = "\\temp\\"

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    
Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process where name = 'wscript.exe' or name = 'cscript.exe'")

If colProcess.Count > 1 Then
	'  --- a wscript or cscript process is already running
	WScript.quit
End If

' Create the event sink object that receives the events
Set objSink = wscript.CreateObject("WbemScripting.SWbemSink", "SINK_")

strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
objWMIService.ExecNotificationQueryAsync objSink, "SELECT * FROM __InstanceOperationEvent WITHIN 3 " & _
"Where Targetinstance Isa 'CIM_DataFile' And " & _
"TargetInstance.Drive = '" & strDrive & "' And " & _
"TargetInstance.Path = '" & strFolder & "'"

Done = False

Do Until Done ' We'll end after first event for this example
	wscript.sleep 1000
Loop

filesys.CopyFile "C:\temp\test.txt", strdir, True 'copy file


Msgbox "All Done"


Sub SINK_OnObjectReady(wmiObject, wmiAsyncContext)
	wscript.echo wmiObject.Path_.Class ' what event was it?
	wscript.echo wmiObject.TargetInstance.Name
	Done = True
End Sub
 
I'll take a stab at it. I doubt this is the simplest or best way to do it, but here goes...
Each time this script is run it will make a copy of the file, prepending a timestamp to the file name. It then gathers all the timestamped files in a list, sorts the list and deletes the files above the number you specify to keep.

Important note: for the array list to work, the .NET framework will need to be installed on the computer that the script is run on.

Code:
Option Explicit

Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
Dim myFolder, inputFolder, outputFolder, objFile, timestamp, inputFile, outputFile
Dim myArrayList, myOutputFolder, i, oldFile

'change the following values as necessary
Const numToKeep = 10
inputFolder = "C:\Temp"
outputFolder = "C:\Temp\test"
Set inputFile = objFSO.GetFile("C:\Temp\testresults.txt")

'timestamp will be 14 digits long
timestamp = Year(Now()) & Right("00" & Month(Now()), 2) & Right("00" & Day(Now()), 2) & Hour(Now()) & Right("00" & Minute(Now()), 2) & Right("00" & Second(Now()), 2) & "_"
'msgbox(timestamp)

if not objFSO.FolderExists(outputFolder) then
	msgbox(outputFolder & " does not exist, script exiting")
end if

outputFile = objFSO.BuildPath(outputFolder, timestamp & objFSO.GetBaseName(inputFile) & "." & objFSO.GetExtensionName(inputFile))
objFSO.CopyFile inputFile, outputFile

'the .net framework will need to be installed on target machine for arraylist to work
Set myArrayList = CreateObject( "System.Collections.ArrayList" )
Dim re
set re = new regexp
'look for 14 digit timestamp followed by "_filename"
re.Pattern ="\d{14}_" & objFSO.GetBaseName(inputFile)
re.IgnoreCase = true
re.Global = true

set myOutputFolder = objFSO.GetFolder(outputFolder)
'msgbox(myOutputFolder.Files.Count)
for each objFile in myOutputFolder.Files
	'msgbox(objFile.Name)
	if re.Test(objFile.Name) then
		'add timestamped files to list
		myArrayList.Add(objFile.Name)
	end if
next

'msgbox("Count: " & myArrayList.Count)
if myArrayList.Count > numToKeep then
	myArrayList.Sort
	myArrayList.Reverse
	'list of timestamped files is not reverse sorted (newest = first)
	for i = numToKeep to myArrayList.Count - 1
		oldFile = objFSO.BuildPath(outputFolder, myArrayList(i))
		'delete old files
		objFSO.DeleteFile(oldFile)
	next
end if

msgbox("Done")
 
jges, thanks very much for your time and help on this. This does EXACTLY what I need and works perfectly. I appreciate your help and can't thank you enough.
 
Glad to be of help!

I just noticed a typo in a comment near the end of the script
Code:
'list of timestamped files is [s][COLOR=#CC0000]not[/color][/s] [COLOR=#4E9A06]now[/color] reverse sorted (newest = first)

Normally, I wouldn't bother with a typo in a comment; but this one negates the meaning of the comment!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top