tags:

views:

355

answers:

3

I'm writing a VBScript for SyncBack (backup utility) in which I am deleting old versions of a backup.

    '' # if current version is greater than the total allowed number of versions,
 '' # delete the oldest folder
 If versionNumber > totalVersions Then
  delDirNum = versionNumber - totalVersions
  If delDirNum > 0 Then
   DelFoldername = containerFileOrFolder & "\" & delDirNum & "_"
               '' " # Ignore this line SO Prettify doesn't do VB very well. 
   If fso.FolderExists(DelFoldername) = True Then
    WScript.Echo "Deleting: <" & DelFoldername & ">"
    Set oFolder = objFileSystem.GetFolder(DelFoldername)
    oFolder.Delete()
    WScript.Sleep 2000
    If fso.FolderExists(DelFoldername) = False Then
     WScript.Echo "Deleted <" & DelFoldername & "> successfully"
    Else
     WScript.Echo "Could not delete <" & DelFoldername & ">"
    End If
   End If
  End If
 End If

However, occasionally the folder (that contains the old backup) which I am trying to delete takes longer that the 2 seconds at WScript.Sleep 2000 to remove and I was wondering if there was a way of making the script wait until the folder has been deleted before it prints out "Deleted <foldername> successfully".

Ideally I'd love something like:

While oFolder.IsDeleting() Then
    WScript.Echo "Still deleting..."
    WScript.Sleep 2000
Loop

But I'm well aware that that's probably not going to be the case.

+3  A: 
While fso.FolderExists(DelFoldername)
   WScript.Echo "Still deleting"
   WScript.Sleep 1000
Wend
C. Ross
That's what I was going to do, but what if the script can't delete the folder? Infinite loop?
Jon
If you have On Error Resume on it will, if not, the error will automatically abort.
C. Ross
+2  A: 

You could move the delete into it's own function and add a timeout. so if the folder is not deleted in a reasonable amount of time the function returns without deleting the folder. Something like this:

Function DeleteFolder(Folder, Timeout)
'Folder is the full file path of the folder
'Timeout is the amount of time to wait for the folder to be deleted (in seconds).
    On Error Resume Next
    Set fso = CreateObject("Scripting.FileSystemObject")
    If fso.FolderExists(Folder) Then
     fso.DeleteFolder Folder, True
     start = Now()
     do while fso.FolderExists(Folder) AND DateDiff("s",start,Now()) < Timeout
      wscript.sleep 1000
     Loop
    End If
    If fso.FolderExists(Folder) Then
     DeleteFolder = False
    Else 
     DeleteFolder = True
    End If
End Function

Then call the function like this

If DeleteFolder("C:\New Folder", 5) Then
    Wscript.Echo "Folder Deleted"
Else
    Wscript.Echo "Folder could NOT be deleted" 
End If

WARNING: Using On Error Resume Next is not recomended.
This command will cause all errors to be ignored, and should only be used under adult supervision.

Side effects may include: Strange errors in other parts of a script, unexpected script action, headache, dizziness, confusion, anger, or a sudden urge to curse. In rare cases this command has been known to cause bleeding from the eyes and ears. Using this command may lead to hair and job loss.

Tester101
Why would you use On Error Resume Next ?
AnthonyWJones
Because I don't care about errors in this function, I only care if the folder was deleted or not. Should the script abort if it encounters an error? From looking at the OP's code I would say they don't want the script to stop, they just want to know if the folder was deleted or not.
Tester101
Is there really no other way of doing this other than guessing the maximum time that it would take to delete a folder and using that as the limit?
Jon
@Tester101: Are you sure that when any possible error happens the function returns the appropriate True or False value in all circumstances?
AnthonyWJones
@Jon: I can't think of any way to know how long a folder should take to delete, other than deleting a bunch of folders of the same size containing the same file types of the same size and time it. Then you could take an average and use that as the timeout, short of that I can't think of a way of knowing how long the operation should take.
Tester101
@Anthony: I'm not sure I understand why you are asking. Can I be sure that this function will work in every possible situation? no. But I am pretty sure that after the timeout elapses if the folder still exists it will return false. I guess I could setup and test every possible situation, but who has the time? I would think that almost nobody knows if there code will work in every possible situation.
Tester101
@Tester101: I feel much better now. ;)
AnthonyWJones
+1  A: 

Loop sleep with counter, note assumes CScript host which makes the "Still Deleting" message a bit more palettable. The delay in the example is 30 seconds.

Dim loopCount : loopCount = 0
WScript.StdOut.Write "Deleting ."
Do While fso.FolderExists(DelFoldername) And loopCount < 30
   WScript.Sleep 1000
   WScript.StdOut.Write "."
   loopCount = loopCount + 1
Loop
WScript.StdOut.Write vbCrLf
If fso.FolderExists(DelFolderName) Then
   '' # Do stuff due to failure.
End If
AnthonyWJones
Is there really no other way of doing this other than guessing the maximum time that it would take to delete a folder and using that as the limit?
Jon
You were concerned about waiting indefinitely so there must be a limit. So the question becomes "How do I determine what is the maximum amount of time to wait until I can be sure that the folder delete has definitely failed?". This is an impossible question to answer but we can use some common sense and modify it to "what is the maximum __reasonable__ amount of time...". My advice, use 300 seconds and then wait and see how many times that turns out to not cover it, my money is on None.
AnthonyWJones
My concern was about waiting indefinitely in the case that the folder could not be deleted. @Tester101's inclusion of the "On Error..." is useful because that should ensure the wait is not infinite in the case that an error occurs when deleting the folder and its contents. Aside from that I will probably have to make up a limit as you've suggested.
Jon
I guess there is a difference in approach to administrative scripting than typical developer practice. I would avoid On Error Resume Next like the plague tucking it away and a line of code protected by it in a small function, certainly wouldn't let prevail over just any sundry code. In such case there would be no fear that an error will cause an infinite loop, because an error would do what its suppose to do.
AnthonyWJones
I have added a warning to my post. Hopefully it will make you feel more at ease with my use of On Error Resume Next.
Tester101