Clay Willing
asked on
vba code to check folder size doesn't work on Win 7 PC's
I have an access based file monitor app that basically scans folder sizes to see if they have increased after x seconds (set by form timer property). Each folder being scanned is being filled with data sniffed from winsockets and creating text files of data received and due to my winsocket program, i can see the data arriving so the data is indeed being stored.
The code uses the filesystemobject - folder.size property to test for change and works perfectly well on Win XP PC's running Office 2010. However when i copy the same accdb onto a win 7 machine, the code runs without error but does not detect and therefore update the underlying table.
I also re-wrote the code to iterate through sub folders to get the accumulated and therefore ultimate parent folder size and I get the same effect. It just refuses to detect any change in the folder size.
Bizarrely, with the code running and showing my form, (a text box shows green if the folder size displayed in the box increases and reverts to red if the size remains the same) and I open a subfolder that I am testing with windows explorer, which shows the latest stored file, i can see the file size in details view change from zero to the proper size and my program responds appropriately. If I do nothing, again the size reverts to the same as listed previously. Once again, if I hit F5, the size in Win Ex changes and the program instantly responds.
I initially suspected some form of Windows 7 vaguery, so I borrowed a PC with a completely vanilla install of win 7 and got the same effect.
I have also checked Access references to ensure the scripting objects etc are all the same. Has anyone else come across a similar effect when using the fso?
I will post the detection code when I get back to my other PC.
Kind regards, a rather stumped vba access programmer
The code uses the filesystemobject - folder.size property to test for change and works perfectly well on Win XP PC's running Office 2010. However when i copy the same accdb onto a win 7 machine, the code runs without error but does not detect and therefore update the underlying table.
I also re-wrote the code to iterate through sub folders to get the accumulated and therefore ultimate parent folder size and I get the same effect. It just refuses to detect any change in the folder size.
Bizarrely, with the code running and showing my form, (a text box shows green if the folder size displayed in the box increases and reverts to red if the size remains the same) and I open a subfolder that I am testing with windows explorer, which shows the latest stored file, i can see the file size in details view change from zero to the proper size and my program responds appropriately. If I do nothing, again the size reverts to the same as listed previously. Once again, if I hit F5, the size in Win Ex changes and the program instantly responds.
I initially suspected some form of Windows 7 vaguery, so I borrowed a PC with a completely vanilla install of win 7 and got the same effect.
I have also checked Access references to ensure the scripting objects etc are all the same. Has anyone else come across a similar effect when using the fso?
I will post the detection code when I get back to my other PC.
Kind regards, a rather stumped vba access programmer
Perhaps you need to have the code open the explorer (in the background possibly hidden) to the location that it's checking to have it update correctly. At least that's what it sounds like worked in your description. I don't work as much with Access so I don't have any code to provide.
Could you show your code?
I have used FSO on windows 7 to get the folder size, although admittedly at startup, not continuously.
I have used FSO on windows 7 to get the folder size, although admittedly at startup, not continuously.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
Also, you might want to try the built-in VBA verbs to handle this rather than FSO. DIR() and Filelen() are available.
Jim.
Jim.
ASKER
Thanks Jim I definitely think it's to do with the OS. I will have to look up those 2 constructs and see if I can modify the approach but that will have to wait until tomorrow. Will get back to you
However I don't want to check for files because they are only created once an hour and I need to check in close to real time so my guys can react if data is lost.
I had thought of capturing the socket activity instead but I also use lab view to capture some of the data so I need an independent method which was working well on xp
As I left the laptop at work I will have to update you all tomorrow
Thanks so far
E
However I don't want to check for files because they are only created once an hour and I need to check in close to real time so my guys can react if data is lost.
I had thought of capturing the socket activity instead but I also use lab view to capture some of the data so I need an independent method which was working well on xp
As I left the laptop at work I will have to update you all tomorrow
Thanks so far
E
ASKER
Here's my code that runs on timer event set in form open sub
As you can see in this version, I iterate through subfolders to check the size. The original does it at line 1110 with
1110 Param = Round(fsoFolder.Size / 1024, 2)
I also forgot to mention that I have also tested for DateLastAccessed and DateLastModified of the scripting.filesystemobject . Neither of those would update until the folder was opened in win exp either.
1112 FldAccDate = fsoFolder.DateLastAccessed
1114 FldModDate = fsoFolder.DateLastModified
As you can see this is quite frustrating.
My next step is to investigate this construct instead:
Dim getInfo As System.IO.DirectoryInfo
getInfo = My.Computer.FileSystem.Get DirectoryI nfo _
(My.Computer.FileSystem.Sp ecialDirec tories.MyD ocuments)
MsgBox("The directory was created at " & getInfo.CreationTime)
MsgBox("The directory was last accessed at " & getInfo.LastAccessTime)
MsgBox("The directory was last written to at " & getInfo.LastWriteTime)
But I don't know what dependencies and references I need in VB to get access to this.....yet
Anyway my working code on an xp box looks like this:
As you can see in this version, I iterate through subfolders to check the size. The original does it at line 1110 with
1110 Param = Round(fsoFolder.Size / 1024, 2)
I also forgot to mention that I have also tested for DateLastAccessed and DateLastModified of the scripting.filesystemobject
1112 FldAccDate = fsoFolder.DateLastAccessed
1114 FldModDate = fsoFolder.DateLastModified
As you can see this is quite frustrating.
My next step is to investigate this construct instead:
Dim getInfo As System.IO.DirectoryInfo
getInfo = My.Computer.FileSystem.Get
(My.Computer.FileSystem.Sp
MsgBox("The directory was created at " & getInfo.CreationTime)
MsgBox("The directory was last accessed at " & getInfo.LastAccessTime)
MsgBox("The directory was last written to at " & getInfo.LastWriteTime)
But I don't know what dependencies and references I need in VB to get access to this.....yet
Anyway my working code on an xp box looks like this:
Public Sub CheckFolder()
On Error GoTo CheckFolderErr:
'Close the form
Dim db As Database
Dim rsSize As DAO.Recordset
Dim strSQL As String
Dim strSpeech As String
Dim fso As Object
Dim fsoFolder As Object
Dim fsoSubs As Object
Dim fsosubFld As Object
Dim Ctrl As Control
Dim CtrlName As String
Dim subSize As Double
Dim FinalSub As Double
' Const strFolderName As String = "C:\My Documents"
1000 Set db = CurrentDb
1010 strSQL = "SELECT * FROM FileSizes WHERE [InUse] = True"
1020 Set rsSize = db.OpenRecordset(strSQL, dbOpenDynaset)
1030 rsSize.MoveFirst
1040 Do While Not rsSize.EOF
1042 subSize = 0
'************Get Folder Path*************
1050 strFilePath = rsSize![FilePath]
'1050 strFileName = rsSize![FileName] '*******use this line for file size instead
'************Set the previous folder size in the OldSize Field*************
1060 rsSize.Edit
1070 rsSize![OldSize] = rsSize![NewSize]
'1072 txtOldSize.Value = rsSize![OldSize]
1080 rsSize.Update
'************Check how big it is now*************
'1100 Param = FileLen(strFilePath & strFileName) /1024 '*************Use this line for file size instaed
1090 Set fso = CreateObject("Scripting.FileSystemObject")
1100 Set fsoFolder = fso.GetFolder(strFilePath)
1102 Set fsoSubs = fsoFolder.SubFolders
1104 For Each fsosubFld In fsoSubs
1106 subSize = subSize + fsosubFld.Size
1108 Next
1111 FinalParam = FormatNumber(subSize / 1048576, 5)
'************Update the new size field*************
1120 rsSize.Edit
1130 rsSize![NewSize] = FinalParam
'1132 txtNewSize.Value = FinalParam
1140 rsSize.Update
'************Compare values and make alert sound*************
1150 If rsSize![OldSize] = rsSize![NewSize] Then
1160 strSpeech = rsSize![Dataname]
1170 ANNOUNCE (strSpeech)
1180 CtrlName = rsSize![filetrap]
1190 Set Ctrl = Me.Controls(CtrlName)
1200 Ctrl.BackColor = vbRed
1210 If rsSize![fired] = False Then
1220 rsSize.Edit
1230 rsSize![timelost] = Now
1240 rsSize![fired] = True
1250 rsSize.Update
1260 End If
1270 Else
'************If no missing then turn traffic light green and set flag****************
1280 CtrlName = rsSize![filetrap]
1290 Set Ctrl = Me.Controls(CtrlName)
1300 Ctrl.BackColor = vbGreen
1305 Ctrl.Value = rsSize![NewSize]
1310 rsSize.Edit
1320 rsSize![fired] = False
1330 rsSize.Update
1340 End If
1350 rsSize.MoveNext
1360 Loop
9000 rsSize.Close
9010 Set rsSize = Nothing
9020 db.Close
9030 Set db = Nothing
9040 Set fsoFolder = Nothing
9050 Set fso = Nothing
CheckFolderExit:
Exit Sub
CheckFolderErr:
FormNametxt = "CheckFolder"
ProcNametxt = "CheckFolder"
MsgBox "There has been an error. Please report it to Developer." & vbCrLf & "Error Produced was " & Err.Number & " = " & Err.Description, vbExclamation
Call ErrorCheck(FormNametxt, ProcNametxt)
GoTo CheckFolderExit
End Sub
ASKER
Hmmmm.......
Looking at directoryinfo, getdirectoryinfo via the filesystem object is not recognised by the access debugger and tells me it is a user defined type not recognised. Annoying.
Mike In IT:
opening the parent folder that i was testing the size of has no effect, it has to be the last folder that contains the last file that is being written to to update correctly. Using your suggestion I would have to open win exp and get it to refresh each subfolder after finding a way to find out which was the last one created each time.
Can someone help me understand how to get access to the FileSystemInfo Class in vba? In here it describes a method to refresh the class as otherwise the data such as we are trying to get from the code above will be out of date.
Alternatively I think I am onto something here if I can find a refresh method for the fso class then i have a solution for my code above.
Looking at directoryinfo, getdirectoryinfo via the filesystem object is not recognised by the access debugger and tells me it is a user defined type not recognised. Annoying.
Mike In IT:
opening the parent folder that i was testing the size of has no effect, it has to be the last folder that contains the last file that is being written to to update correctly. Using your suggestion I would have to open win exp and get it to refresh each subfolder after finding a way to find out which was the last one created each time.
Can someone help me understand how to get access to the FileSystemInfo Class in vba? In here it describes a method to refresh the class as otherwise the data such as we are trying to get from the code above will be out of date.
Alternatively I think I am onto something here if I can find a refresh method for the fso class then i have a solution for my code above.
ASKER
Jim, I have assigned you as the best solution. Ultimately, it is the underlying OS which has floored my code and I am going to adjust my approach. I am either going down the system file IO constructs to use an updated method of the current one or I will modify some of the data capture code to light a traffic light using winsockets. I use them to capture port traffic from TCP sources and create the analysis data, I will need to do the same for the UDP based ports too which may prove to be more challenging.