VBScript OpenTextFile File Not Found error when Windows Explorer shows the file

Viewed 540

I am writing a program in VBScript to automate the process of file encryption, and am struggling with a problem.

I want to test which code the script will execute based on whether a file comparison returns an errorlevel of 0 or 1. (For simplicity, I cut out that code from this post.) Google searches have pointed me to the following to start the process of modifying one of the comparison files for this purpose.

Set testFile = fso.OpenTextFile(testDestFile, 8, False, 0)

However, VBScript always throws a "File not found" error for that line unless I put

WScript.Echo "testDestFile is '" & testDestFile & "'..."

right before it.

I don't want that, because the script's actions should be invisible to the user unless necessary. When I run this script, I can see in Windows Explorer that it creates the file represented by testDestFile. What am I doing wrong?

Option Explicit

Dim baseDirLen, compareOpts, decryptOpts, destDataPath, destFolder, _
   destFolderPath, encDestFile, encryptorPath, encryptOpts, file, fileName, _
   folder, folderEnd, fso, keyPath, oShell, srcDataPath, srcDirEndLen, _
   srcFolder, strErrorCode, testDestFile, testDiff, testFile, t

Set oShell = CreateObject("Wscript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
srcDataPath = "e:\EZcrypt\TargetData"
keyPath = "e:\EZcrypt\Key\Demo010719.key.bin"
destDataPath = "E:\EZcrypt\EncryptedData"
encryptorPath = "E:\OpenSSL-Win32\bin\openssl"

Set srcFolder = fso.GetFolder(srcDataPath)
baseDirLen = Len(srcDataPath)

recurseFolders(srcFolder)

Sub recurseFolders(srcFolder)
    For Each folder In srcFolder.subfolders
        srcDirEndLen = (Len(folder) - baseDirLen - 1)
        folderEnd = Right(folder, srcDirEndLen)
        destFolderPath = destDataPath & "\" & folderEnd & "\"

        If Not fso.FolderExists(destFolderPath) Then
            fso.CreateFolder(destFolderPath)
        End If

        For Each file In folder.Files
            fileName = fso.GetFileName(file)
            testDestFile = destFolderPath & "test." & fileName
            encDestFile = destFolderPath & fileName & ".enc"

            If Not fso.FileExists(encDestFile) Then
                strErrorCode = ""
                encryptOpts = encryptorPath & " enc -aes-256-cbc -salt -in """ & _
                              file & """ -out """ & encDestFile & _
                              """ -pass file:""" & keyPath & """ -pbkdf2"
                oShell.Run (encryptOpts)
                decryptOpts = encryptorPath & " enc -d -aes-256-cbc -in """ & _
                              encDestFile & """ -out """ & testDestFile & _
                              """ -pass file:""" & keyPath & """ -pbkdf2"
                oShell.Run (decryptOpts)
                WEcript.Echo "testDestFile is '" & testDestFile & "'..."
                Set testFile = fso.OpenTextFile(testDestFile, 8, False, 0)                    
            Else
                WScript.Echo "'" & encDestFile & "' exists. Skipping..."
            End If
        Next
        recurseFolders(folder)
    Next
End Sub
1 Answers

The most likely reason for the behavior you observed is that the openssl commands you run right before trying to open that file (specifically the encryption command, which appears to be creating the file) haven't finished yet. You don't tell the Run method to wait for the commands to return, so they're running asynchronously in the background. Presumably the WScript.Echo adds just enough delay for the encryption to finish before the code proceeds to opening the file. Using WScript.Sleep instead of echoing something would probably have had the same effect.

To fix the issue, wait for the external commands to return.

Replace these lines:

encryptOpts = encryptorPath & ...
oShell.Run (encryptOpts)
decryptOpts = encryptorPath & ...
oShell.Run (decryptOpts)

with this:

encryptOpts = encryptorPath & ...
oShell.Run encryptOpts, 0, True
decryptOpts = encryptorPath & ...
oShell.Run decryptOpts, 0, True

It's also good practice to check the exit status of external commands, so you can see if something went wrong:

rc = oShell.Run(encryptOpts, 0, True)
If rc <> 0 Then
    'an error occurred
End If
Related