Best_Where_Gives
Best_Where_Gives

Reputation: 481

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

Upvotes: 4

Views: 2126

Answers (3)

Best_Where_Gives
Best_Where_Gives

Reputation: 481

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

Upvotes: 2

Bond
Bond

Reputation: 16311

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.

Upvotes: 1

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

Upvotes: 0

Related Questions