Changing name of directory containing read-only files - vbscript

I am trying to get this script to work, it gets 4 arguments and ends renaming the the folder (FDirectory) removing spaces and starting a batch file with the new arguments. The problem is that it returns an error "access denied" for folders containing read-only files. Is there a way to get this to work? Thanks in advance.
Set WshShell = CreateObject("WScript.Shell")
currentDirectory = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName)))
length = Len(currentDirectory)
State = WScript.Arguments.item(0)
Directory = Left(WScript.Arguments.item(1),length+6)
FDirectory = Replace(WScript.Arguments.item(1)," ",".")
Kind = WScript.Arguments.item(2)
Message = WScript.Arguments.item(3)
'change folder name
If (kind = "multi") And (Directory = currentDirectory & "SFetch") then
Set FS = CreateObject("Scripting.FileSystemObject")
FS.MoveFolder WScript.Arguments.item(1),Replace(WScript.Arguments.item(1)," ",".")
END IF
currentDirectory = currentDirectory & "Rename.bat "
WshShell.RUN currentDirectory & State & " " & Directory & " " & FDirectory & " " & Kind & " " & Message, 0, True
Set WshShell = Nothing

Read-only files don't create an issue - but renaming a folder with open files inside it, or renaming the current working directory will create problems.

Related

VB SCRIPT The system can not find the file specified ON SOME COMPUTERS/USERS

Good day! I have this script that opens up an access application.
This script works on several users but one. This user is getting this error
"Error 80070002: The system can not find the file specified".
I'm quite sure there is nothing wrong with my script as only one person is encountering this issue.
Could there be a computer setting or update that is causing this problem?
Everything works except for the Open File part.
And this is for some computers/user only. Most of the Computer/users can execute this without any problem.
Thanks in advance!
Here's the script
'*******************************************************************************
'Find user name
'*******************************************************************************
Set WshNetwork = CreateObject("WScript.Network")
userName = WshNetwork.UserName
Set WshNetwork = Nothing
'*******************************************************************************
'Find version of master file
'*******************************************************************************
Set folder = objfso.GetFolder(folderPath)
For Each file In folder.Files
If InStr(file.Name, "AMSDshbd_M") = 1 Then
masterVersion = Mid(file.Name, 11, (InStrRev(file.Name, ".") - 11))
Exit For
End If
Next
'*******************************************************************************
'Find version of user file, if it exists
'*******************************************************************************
isUserFile = 0
For each file In folder.Files
If InStr(file.Name, "AMSDshbd_" & userName) = 1 Then
isUserFile = 1
userVersion = Mid(file.Name, (Len(userName) + 10), (InStrRev(file.Name, ".") - (Len(userName) + 10)))
Exit For
End If
Next
'*******************************************************************************
'Copy the file if no user file exists or if the user version is not current
'*******************************************************************************
sourceFile = folderPath & "AMSDshbd_M" & masterVersion & ".accde"
targetFile = folderPath & "AMSDshbd_" & userName & "_M" & masterVersion & ".accde"
isCopyNeeded = 1
if isUserFile = 1 then
if userVersion = masterVersion then
isCopyNeeded = 0
end if
end if
if isCopyNeeded = 1 then
objFSO.CopyFile sourceFile, targetFile, True
end if
'*******************************************************************************
'Open the file
'*******************************************************************************
sComTxt = Chr(34) & microsoftAccessFile & Chr(34) & " " & Chr(34) & targetFile & Chr(34)
'objShell.Run sComTxt
objShell.Run sComTxt,,true
Set objFSO = Nothing
Set objShell = Nothing
I figured out what happened. the variable "microsoftAccessFile" is the path to the MS Access EXE, some of the users have a different path to this Access EXE that's why it doesn't work for them. I identified the path where their Access EXE is stored and changed the script for them and it works now. Thanks for pointing out the variable

Unable to find file in VBScript

The VBE encoder section works (from prior experience but this time around it cannot find the required file. The file is in the %temp% folder so there are spaces in the path but I have used the "" as can be seen in the code. The MsgBox shows the correct file and I can confirm its existence but the code fails when fso.GetFile.
This is part of a larger script that is called with the target file (full path) as the argument. The target file is previously created by the calling script.
Main script (gets called with target file):
Set fso = CreateObject("Scripting.FileSystemObject")
Set wshShell = WScript.CreateObject("WScript.Shell")
textFile = WScript.Arguments(0)
GetExtension = fso.GetExtensionName(fso.GetFileName(textFile))
If LCase(GetExtension) = "vbs" Then
Set oFilesToEncode = WScript.Arguments
Set oEncoder = CreateObject("Scripting.Encoder")
For i = 0 To oFilesToEncode.Count - 1
file = """" & Trim(oFilesToEncode(i)) & """"
MsgBox file
If fso.FileExists(Left(file, Len(file) - 3) & "vbe") Then fso.DeleteFile(Left(file, Len(file) - 3) & "vbe")
Set oFile = fso.GetFile(file)
Set oStream = oFile.OpenAsTextStream(1)
sSourceFile = oStream.ReadAll
oStream.Close
sDest = oEncoder.EncodeScriptFile(".vbs", sSourceFile, 0, "")
sFileOut = Left(file, Len(file) - 3) & "vbe"
Set oEncFile = fso.CreateTextFile(sFileOut)
oEncFile.Write sDest
oEncFile.Close
Next
End If
WScript.Quit
Section of calling script:
Do While fso.FileExists(strTempVBS) = False
Loop
strKey = "HKEY_CLASSES_ROOT\Engineers-Toolbox\Multi-Tool\Installed\Path\"
value = wshShell.RegRead( strKey )
arg = " " & strTempVBS
running = "C:\Custom\Multi-Tool\Multi-Tool.exe " & """" & arg & """"
wshShell.Run running, True
I have tried using hard coding the path to the exe to get it going, 'value' contains the path to the main script.
Do not prematurely add quotes around paths. I'm always confused why people keep doing this, because it creates more problems than it solves. Add double quotes when they're actually required, but not before.
FileSystemObject methods can handle paths with spaces without the additional double quotes. In fact, they will interpret double quotes in a path string as part of the path and throw an error, because they can't find a file with a double quote in its name (which would be invalid anyway).
Your check for the existence of a file also doesn't work, because you don't account for the quotes you added to the path string:
file = """C:\some\folder\file.vbs"""
WScript.Echo file
WScript.Echo Left(file, Len(file) - 3) & "vbe"
The output of the above code snippet is
"C:\some\folder\file.vbs"
"C:\some\folder\file.vvbe
Change this:
file = """" & Trim(oFilesToEncode(i)) & """"
into this:
file = Trim(oFilesToEncode(i))
and the problem will disappear.
Ok, the solution is to (predictably) add the quotes in the calling script, that way the VBS to VBE encoder section can remain standard.
strTEMP = wshShell.ExpandEnvironmentStrings( "%UserProfile%" ) & "\AppData\Local\Multi-Tool\"
strTempVBS = strTEMP & "observe.vbs"
strKey = "HKEY_CLASSES_ROOT\Engineers-Toolbox\Multi-Tool\Installed\Path\"
value = wshShell.RegRead( strKey ) & " "
running = value & "" & chr(34) & strTempVBS & chr(34) & ""
wshShell.Run running ,True
Interesting was how the quotes are added. This made the called script find the required file even tho the full path contained spaces.

VBScript Environment variables

I have a question regarding how I should go about fixing an error that I am seeing when running my script. I am pretty sure it has to do with the way in which I am using the %COMPUTERNAME% environment variable.
What my script does is it zips up some files locally, then copies them using robocopy to a mounted or shared drive, then checks to see if the file sizes are the same, and if they are then it deletes the files on the original computer. If any step in the process produces an error it exits the script.
Now the script works perfectly fine if I do not add in the "%COMPUTERNAME%" to the final destination path. (Where the zipped files will eventually be) I need the zipped files to be placed into their own folders with the name of the host from which it originated, because this script will be run on many different machines all going to the same location.
So basically it needs to look something like this:
E:\LocalHostName\TestZip.zip
Now the script will build the folder just fine when the zipped files are being copied over, the problem occurs once the file size check starts. I am getting the error of "File not found" for the line "FileToBeCompared2". I understand why the error is being produced, because it is not recogizing the %COMPUTERNAME% environment variable, but I do not know how to go about addressing this issue.
I am also going to try to add in some functionality where if an error occurs a text file with something like "An error occured during the script" is produced in the output folder.
Thank you for all your help in advance. The script is found below:
'-------------------------------------------------------------------------------------------
'This script is used to zip files locally, copy them to a new location, verify that the
'files were copied correctly, and then delete the files from the original source.
'In it's current state it is being used as a means to zip event files and move them
'to a central location.
'Run with administrator priveleges.
'-----------------------------------------------------------------------------------------------------
Option Explicit
Dim sDirectoryPath, sLocalDestinationPath, sFinalDestinationPath, sOutputFilename, Shell, sFileExt, sFilePrefix
Set Shell = WScript.CreateObject("WScript.Shell")
'Specify Directory Path where files to be zipped are located
'Specify local destination for zipped files
'Specify final destination path for zippped files
'Specify file extension name to look for
'Specify prefix of filename to look for
sDirectoryPath = "C:\Testscripts\"
sLocalDestinationPath = "C:\ScriptOutput\"
sFinalDestinationPath = "E:\CopyTestFolder\" & sOutputFilename & "\"
sFileExt = ".evtx"
sFilePrefix = "Archive*"
sOutputFilename = shell.ExpandEnvironmentStrings("%COMPUTERNAME%") 'Environment variables needed for grabbing hostname
Dim ZipCommand, RobocopyCommand, RunCommand, filesys, filetext
Dim d : d = Date()
Dim dateStr : dateStr = Year(d) & "-" & Right("00" & Month(d), 2) & "-" & Right("00" & Day(d), 2) 'Date String
Dim t : t = Time()
Dim timeStr: timeStr = Hour(t) & "-" & Right("00" & Minute(t), 2) & "-" & Right("00" & Second(t), 2) 'Time String
Dim FullFileName
FullFileName = sOutputFilename & "-" & dateStr & "-" & timeStr & ".zip "
'Following command runs 7-zip and grabs the files to be zipped from your set sDirectoryPath, zips them into set sLocalDestinationPath
'and names the file with the localhost name and date/time
ZipCommand = """C:\Program Files\7-zip\7z.exe"" a " & sLocalDestinationPath & FullFileName & sDirectoryPath & sFilePrefix & sFileExt
RunCommand = Shell.Run(ZipCommand,0,true)
if err.Number <> 0 then
WScript.Echo "An error has occurred during the zip process, re-run Script." WScript.Quit
end if
Wscript.Sleep 2000
'The following command creates a folder named after the host computer where the files are being copied from
Dim newfolder, newfolderpath, filesys2
newfolderpath = "E:\CopyTestFolder\" & sOutputFilename & "\"
set filesys2 = CreateObject("Scripting.FileSystemObject")
If Not filesys2.FolderExists(newfolderpath) Then
Set newfolder = filesys2.CreateFolder(newfolderpath)
End If
'Following command runs Robocopy from command line, moves files from your set sLocalDestinationPath to your set sFinalDestinationPath
WScript.Echo "Robocopy.exe " & sLocalDestinationPath & " " & sFinalDestinationPath
RobocopyCommand = "Robocopy.exe " & sLocalDestinationPath & " " & sFinalDestinationPath
RunCommand = Shell.Run(RobocopyCommand,0,true)
if err.Number <> 0 then
WScript.Echo "An error has occured copying the files, re-run Script."
WScript.Quit
end if
Dim fso, FileToBeCompared1, FileToBeCompared2
Set fso = CreateObject("Scripting.FileSystemObject")
'Setting the Local file to be compared
Set FileToBeCompared1 = fso.GetFile(sLocalDestinationPath & FullFileName)
WScript.echo sFinalDestinationPath & FullFileName
'Setting the file copied to final destination to be compared
Set FileToBeCompared2 = fso.GetFile(sFinalDestinationPath & FullFileName)
If FileToBeCompared1.size = FileToBeCompared2.size then
fso.DeleteFile("C:\Testscripts\Archive*.evtx") 'This will be the path where events are being Archived to. (Non restricted path)
fso.DeleteFolder("C:\ScriptOutput") 'This deletes the archive folder that 7-zip builds each time this script is run
else
WScript.Echo "File sizes do not match, File was not fully copied, Re run script."
WScript.Quit
end if
Because fso.GetFile() will not automatically expand %COMPUTERNAME%, modify sFinalDestinationPath to use sOutputFilename like this:
sOutputFilename = shell.ExpandEnvironmentStrings("%COMPUTERNAME%")
sFinalDestinationPath = "E:\CopyTestFolder\" & sOutputFilename & "\"

VBS script 'Path not found' error when setting file system folder object reference

I am writing a script to determine the combined size of all instances of a particular subfolder within the profile folder of each user who has logged onto a Windows 2003 server, e.g. all users' desktop folders or all users' local settings folders.
Option Explicit
Dim colSubfolders, intCount, intCombinedSize, objFolder2, objFSO1, objFSO2, objUserFolder, strOutput, objSearchFolder, objSubfolder, strSearchFolder, strSubfolderPath
intCount = 0
intCombinedSize = 0
strSearchFolder = "C:\Documents and Settings\"
Set objFSO1 = CreateObject("Scripting.FileSystemObject")
Set objSearchFolder = objFSO1.GetFolder(strSearchFolder)
Set colSubfolders = objSearchFolder.SubFolders
For Each objUserFolder in colSubfolders
strSubfolderPath = objUserFolder.Path & "\Desktop\"
Set objFSO2 = CreateObject("Scripting.FileSystemObject")
Set objSubfolder = objFSO2.GetFolder(strSubfolderPath)
intCount = intCount + 1
intCombinedSize = intCombinedSize + objSubfolder.Size
Next
MsgBox "Combined size of " & CStr(intCount) & " folders: " & CStr(intCombinedSize / 1048576) & " MB"
This code throws a 'Path not found' error (Code 800A004C) at line 15:
Set objSubfolder = objFSO2.GetFolder(strSubfolderPath)
If I print out strSubfolderPath, however, I find that all the strings returned are valid directory paths, so I don't understand why I'm getting this error.
I've tried with and without the trailing backslash at the end of the path and I've tried with 8.3 style paths to remove spaces but to no effect.
When I run your code I get the same error.
Upon further inspection, on my computer there is a folder named C:\Documents and Settings\machinename, where machinename is the name of my computer. This folder only contains one subfolder named ASPNet.
I'm guessing you have something similar.
To minimize multiple-backslash confusion, use the FileSystemObject methods consistently instead of relying on string concatenation:
strSubfolderPath = objFSO1.BuildPath(objUserFolder.Path,"Desktop")

Extract files from ZIP file with VBScript

When extracting files from a ZIP file I was using the following.
Sub Unzip(strFile)
' This routine unzips a file. NOTE: The files are extracted to a folder '
' in the same location using the name of the file minus the extension. '
' EX. C:\Test.zip will be extracted to C:\Test '
'strFile (String) = Full path and filename of the file to be unzipped. '
Dim arrFile
arrFile = Split(strFile, ".")
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateFolder(arrFile(0) & "\ ")
pathToZipFile= arrFile(0) & ".zip"
extractTo= arrFile(0) & "\ "
set objShell = CreateObject("Shell.Application")
set filesInzip=objShell.NameSpace(pathToZipFile).items
objShell.NameSpace(extractTo).CopyHere(filesInzip)
fso.DeleteFile pathToZipFile, True
Set fso = Nothing
Set objShell = Nothing
End Sub 'Unzip
This was working, but now I get a "The File Exists" Error.
What is the reason for this? Are there any alternatives?
All above solutions are accurate, but they are not definitive.
If you are trying to extract a zipped file into a temporary folder, a folder that displays "Temporary Folder For YOURFILE.zip" will immediately be created (in C:\Documents and Settings\USERNAME\Local Settings\Temp) for EACH FILE contained within your ZIP file, which you are trying to extract.
That's right, if you have 50 files, it will create 50 folders within your temp directory.
But if you have 200 files, it will stop at 99 and crash stating - The File Exists.
..
Apparently, this does not occur on Windows 7 with the contributions I view above. But regardless, we can still have checks. Alright, so this is how you fix it:
'========================
'Sub: UnzipFiles
'Language: vbscript
'Usage: UnzipFiles("C:\dir", "extract.zip")
'Definition: UnzipFiles([Directory where zip is located & where files will be extracted], [zip file name])
'========================
Sub UnzipFiles(folder, file)
Dim sa, filesInzip, zfile, fso, i : i = 1
Set sa = CreateObject("Shell.Application")
Set filesInzip=sa.NameSpace(folder&file).items
For Each zfile In filesInzip
If Not fso.FileExists(folder & zfile) Then
sa.NameSpace(folder).CopyHere(zfile), &H100
i = i + 1
End If
If i = 99 Then
zCleanup(file, i)
i = 1
End If
Next
If i > 1 Then
zCleanup(file, i)
End If
fso.DeleteFile(folder&file)
End Sub
'========================
'Sub: zCleanup
'Language: vbscript
'Usage: zCleanup("filename.zip", 4)
'Definition: zCleanup([Filename of Zip previously extracted], [Number of files within zip container])
'========================
Sub zCleanUp(file, count)
'Clean up
Dim i, fso
Set fso = CreateObject("Scripting.FileSystemObject")
For i = 1 To count
If fso.FolderExists(fso.GetSpecialFolder(2) & "\Temporary Directory " & i & " for " & file) = True Then
text = fso.DeleteFolder(fso.GetSpecialFolder(2) & "\Temporary Directory " & i & " for " & file, True)
Else
Exit For
End If
Next
End Sub
And that's it, copy and paste those two functions into your VBScript hosted program and you should be good to go, on Windows XP & Windows 7.
Thanks!
You can use DotNetZip from VBScript.
To unpack an existing zipfile, overwriting any files that may exist:
WScript.echo("Instantiating a ZipFile object...")
Dim zip
Set zip = CreateObject("Ionic.Zip.ZipFile")
WScript.echo("Initialize (Read)...")
zip.Initialize("C:\Temp\ZipFile-created-from-VBScript.zip")
WScript.echo("setting the password for extraction...")
zip.Password = "This is the Password."
' set the default action for extracting an existing file
' 0 = throw exception
' 1 = overwrite silently
' 2 = don't overwrite (silently)
' 3 = invoke the ExtractProgress event
zip.ExtractExistingFile = 1
WScript.echo("extracting all files...")
Call zip.ExtractAll("extract")
WScript.echo("Disposing...")
zip.Dispose()
WScript.echo("Done.")
To create a new zipfile:
dim filename
filename = "C:\temp\ZipFile-created-from-VBScript.zip"
WScript.echo("Instantiating a ZipFile object...")
dim zip2
set zip2 = CreateObject("Ionic.Zip.ZipFile")
WScript.echo("using AES256 encryption...")
zip2.Encryption = 3
WScript.echo("setting the password...")
zip2.Password = "This is the Password."
WScript.echo("adding a selection of files...")
zip2.AddSelectedFiles("*.js")
zip2.AddSelectedFiles("*.vbs")
WScript.echo("setting the save name...")
zip2.Name = filename
WScript.echo("Saving...")
zip2.Save()
WScript.echo("Disposing...")
zip2.Dispose()
WScript.echo("Done.")
There's answers above which are perfectly correct, but I thought I'd wrap everything up into a full solution that I'm using:
strZipFile = "test.zip" 'name of zip file
outFolder = "." 'destination folder of unzipped files (must exist)
'If using full paths rather than relative to the script, comment the next line
pwd = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
Set objShell = CreateObject( "Shell.Application" )
Set objSource = objShell.NameSpace(pwd+strZipFile).Items()
Set objTarget = objShell.NameSpace(pwd+outFolder)
intOptions = 256
objTarget.CopyHere objSource, intOptions
'Clean up
Set WshShell = CreateObject("Wscript.Shell")
tempfolder = WshShell.ExpandEnvironmentStrings("%temp%")
Set fso = CreateObject("Scripting.FileSystemObject")
Call fso.DeleteFolder(tempfolder + "\Temporary Directory 1 for " + strZipFile, True )
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_23022290.html
Check your temp directory. If you have 99 folders associated with this unzipping process, try deleting them.
I added the following code to the beginning of my unzip procedure to delete these directories before I unzip:
For i = 1 To 99
If aqFileSystem.Exists(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip") = True Then
result = aqFileSystem.ChangeAttributes(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip", 1 OR 2, aqFileSystem.fattrFree)
Call DelFolder(GetAppPath("Local Settings", "") & "\Temp\Temporary Directory " & i & " for DialogState.zip")
Else
Exit For
End If
Next

Resources