How to run windows executable and delete files from sub folders - vbscript

I need a quick script do two parts.
Run a windows executable
Delete files within a folder and subfolders (*.jpg, *.img).
The first part of the below script works (running the executable) but I am getting stuck on part 2. I get
Cannot use parentheses when calling a sub
The error is on the line with the RecursiveDelete call. I actually cut and pasted that code from another SO question. I have googled the error but still don't understand.
Can anybody know how to get this script working?
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Users\acer\Desktop\CT\process.exe" & Chr(34), 0
Set WshShell = Nothing
Dim PicArray(2)
Dim p
PicArray(1) = "*.jpg"
PicArray(2) = "*.img"
For p = 1 To 2
RecursiveDelete ("D:\pictures", PicArray(p))
Next p
Private Sub RecursiveDelete(ByVal Path As String, ByVal Filter As String)
Dim s
For Each s In System.IO.Directory.GetDirectories(Path)
try
RecursiveDelete(s, Filter)
catch dirEx as exception
debug.writeline("Cannot Access " & s & " : " & dirEx.message
end try
Next
For Each s In System.IO.Directory.GetFiles(Path, Filter)
try
System.IO.File.Delete(s)
catch ex as exception
debug.writeline("Cannot delete " & s & " : " & ex.message)
end try
Next
End Sub
Update: Revised answer from Hackoo that works great.
Option Explicit
Dim fso,RootFolder, wshShell
set fso = CreateObject("Scripting.FileSystemObject")
RootFolder = "D:\pictures"
Set RootFolder = fso.GetFolder(RootFolder)
Call RecursiveDelete(RootFolder)
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\process.exe" & Chr(34), 0
Set WshShell = Nothing
'*****************************************************************************
Function RecursiveDelete(Folder)
Dim File,MyFile,Ext,i,SubFolder
Set Folder = fso.GetFolder(Folder)
For each File in Folder.Files
Set MyFile = fso.GetFile(File)
Ext = Array("iMG","JPG")
For i = LBound(Ext) To UBound(Ext)
If LCase(fso.GetExtensionName(File.name)) = LCase(Ext(i)) Then
MyFile.Delete()
Exit For
end if
Next
Next
For each SubFolder in Folder.SubFolders
Call RecursiveDelete(SubFolder)
Next
End Function
'*****************************************************************************

Try like this way :
Option Explicit
Dim fso,RootFolder
set fso = CreateObject("Scripting.FileSystemObject")
RootFolder = "D:\pictures"
Set RootFolder = fso.GetFolder(RootFolder)
Call RecursiveDelete(RootFolder)
Msgbox "Pictures Cleaned !",vbInformation,"Pictures Cleaned !"
'*****************************************************************************
Function RecursiveDelete(Folder)
Dim File,MyFile,Ext,i,SubFolder
Set Folder = fso.GetFolder(Folder)
For each File in Folder.Files
Set MyFile = fso.GetFile(File)
Ext = Array("jpg","img")
For i = LBound(Ext) To UBound(Ext)
If LCase(fso.GetExtensionName(File.name)) = LCase(Ext(i)) Then
MyFile.Delete()
Exit For
end if
Next
Next
For each SubFolder in Folder.SubFolders
Call RecursiveDelete(SubFolder)
Next
End Function
'*****************************************************************************

Instead of passing the array item into RecursiveDelete, obtain the contents of the array item into a variable within the loop, and pass that variable instead.
Code would be similar to this- did not have a chance to test syntax.
For p = 1 To 2
Dim PicItem
PicItem = PicArray(p)
RecursiveDelete ("D:\pictures", PicItem )
Next p

Related

Long Path Problem using WScript.Arguments

In continuation of Call VBScript from Windows Explorer Context Menu, I managed to get a VBScript file running from SendTo in the Windows Explorer.
I've changed my code to copy the file that invokes the script to my Temp folder. The new problem is that if the path is over 256 characters, I can't loop through WScript.Arguments to get all of it. Is there another way to get the full path (including the file name and it's extension)?
Option Explicit
Call OpenDocuWorksFile
Sub OpenDocuWorksFile()
Const sTitle = "Open DocuWorks File"
Dim iArgumentsCount
Dim iArgument
Dim sFilePath
Dim sTempFolder
Dim oFileScriptingObject
Dim sFileName
Dim oShell
iArgumentsCount = WScript.Arguments.Count
On Error Resume Next
For iArgument = 0 To iArgumentsCount
sFilePath = sFilePath & WScript.Arguments(iArgument)
Next
On Error GoTo 0
Set oFileScriptingObject = CreateObject("Scripting.FileSystemObject")
With oFileScriptingObject
sFileName = .GetFileName(sFilePath)
sTempFolder = oFileScriptingObject.GetSpecialFolder(2) 'Temp Folder
If .GetExtensionName(sFileName) = "xdw" Then
.CopyFile sFilePath, sTempFolder & "\", True 'Overwrite
Set oShell = CreateObject("Shell.Application")
oShell.Open sTempFolder & "\" & sFileName
Else
MsgBox "Please select a DocuWorks file.(.xdw)", vbCritical, sTitle
End If
End With
Set oFileScriptingObject = Nothing
Set oShell = Nothing
End Sub

VBS script to rename files using the pathname

i am new to VBS scripting and I have done few stuff with Excel VBA before. Now I have a script which renames single files with the pathname of the files (truncated to 4 letter each))see below. It is some script which I modified a bit to fit my purpose. However, I would like to automatize the file rename process and rename all files in a folder and its subfolders in the same way the scipt works for single files. Can anybody help me with this question?
Set Shell = WScript.CreateObject("WScript.Shell")
Set Parameter = WScript.Arguments
For i = 0 To Parameter.Count - 1
Set fso = CreateObject("Scripting.FileSystemObject")
findFolder = fso.GetParentFolderName(Parameter(i))
PathName = fso.GetAbsolutePathName(Parameter(i))
FileExt = fso.GetExtensionName(Parameter(i))
Search = ":"
findFolder2= Right(PathName, Len(PathName) - InStrRev(PathName, Search))
arr = Split(findFolder2, "\")
For j=0 To UBound(arr)-1
arr(j) = ucase(Left(arr(j), 4))
Next
joined = Join(arr, "%")
prefix = right(joined, len(joined)-1)
fso.MoveFile Parameter(i), findFolder + "\" + prefix
next
Hoping that I can get some useful ideas.
Herbie
Walking a tree requires recursion, a function calling itself for each level.
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Dirname = InputBox("Enter Dir name")
ProcessFolder DirName
Sub ProcessFolder(FolderPath)
On Error Resume Next
Set fldr = fso.GetFolder(FolderPath)
Set Fls = fldr.files
For Each thing in Fls
msgbox Thing.Name & " " & Thing.DateLastModified
Next
Set fldrs = fldr.subfolders
For Each thing in fldrs
ProcessFolder thing.path
Next
End Sub
From Help on how to run another file.
Set Shell = WScript.CreateObject("WScript.Shell")
shell.Run(strCommand, [intWindowStyle], [bWaitOnReturn])
So outside the loop,
Set Shell = WScript.CreateObject("WScript.Shell")
And in the loop
shell.Run("wscript Yourscript.vbs thing.name, 1, True)
Also the VBS help file has recently been taken down at MS web site. It is available on my skydrive at https://1drv.ms/f/s!AvqkaKIXzvDieQFjUcKneSZhDjw It's called script56.chm.

VBscript Replace text with part of filename

I have a directory of files that I want to Loop through and use part of their filename to replace text in a template doc.
For example one filename may be 'NV_AD32_city.dxf'. All files in the directory follow the same filename pattern of XX_XXXX_string.dxf, using two underscores.
I need to capture the string to the right of the first "_" and to the left of the "."so for this example that would be 'AD32_city'
How do I script to use capture that text of the active file to replace text in the template? I guess I need to create an object? But what is the object to use for the current file from a directory?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Thx for the replies, guys. After several days of trying your code I am just not "getting it". I understand it is set up to take the part of the filename's string that I want but how do I tell the script to use the current file I am looping through? Here is my script so far. I have your code on line 20 under the Sub 'GetNewInputs'
Set fso = CreateObject("Scripting.FileSystemObject")
Option Explicit
Dim WritePath : WritePath = "S:\TempFolder\"
Dim OutFile : OutFile = "VEG_DXF-2-SHP_script-"
Dim WorkingFile : WorkingFile = GetFileContent(SelectFile())
Dim NewState, NewSection, NewArea
Dim OldState, OldSection, OldArea
Call GetNewInputs()
Call GetOldInputs()
Sub GetNewInputs()
NewState = UCase(InputBox("INPUT STATE:", _
"INPUT STATE", "SOCAL"))
NewSection = ("Section_" & InputBox("INPUT SECTION NUMBER:", _
"INPUT SECTION", "14"))
NewArea = "^[^_]+_(.*)\.dxf$"
End Sub
Private Sub GetOldInputs()
OldState = "XX"
OldSection = "_X"
OldArea = "ZZZZ"
End Sub
Function SelectFile()
SelectFile = vbNullString
Dim objShell : Set objShell = WScript.CreateObject("WScript.Shell")
Dim strMSHTA : strMSHTA = "mshta.exe ""about:" & "<" & "input type=file id=FILE>" _
&"<" & "script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _
&".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);" & "<" & "/script>"""
SelectFile = objShell.Exec(strMSHTA).StdOut.ReadLine()
If SelectFile = vbNullString Then
WScript.Echo "No file selected or not a text file."
WScript.Quit
End If
End Function
Private Function GetFileContent(filePath)
Dim objFS, objFile, objTS
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.GetFile(filePath)
Set objTS = objFile.OpenAsTextStream(1, 0)
GetFileContent = objTS.Read(objFile.Size)
Set objTS = Nothing
End Function
For Each FileRefIn fso.GetFolder("S:\SOCAL\Section_14\Veg DXFs\").Files
NewFile = WorkingFile
NewFile = Replace(NewFile, OldState, NewState)
NewFile = Replace(NewFile, OldSection, NewSection)
NewFile = Replace(NewFile, OldArea, NewArea)
WriteFile NewFile, WritePath & OutFile & ".gms"
WScript.Echo NewArea
Next
Private Sub WriteFile(strLine,fileName)
On Error Resume Next
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Do Until IsObject(objFile)
Set objFile = objFSO.OpenTextFile(fileName, 8, True)
Loop
objFile.WriteLine strLine
objFile.Close
End Sub
Well, that’s actually two questions.
To enumerate files in a directory, you can use FileSystemObject, like this (untested)
const strFolderPath = "C:\Temp\Whatever"
set objFSO = CreateObject( "Scripting.FileSystemObject" )
set objFolder = objFSO.GetFolder( strFolderPath )
set colFiles = objFolder.Files
for each objFile in colFiles
' Do whatever you want with objFile
next
Here's the reference of those objects properties/methods.
And to extract portion of file names, you could use a regular expression.
Here’s some guide how to use'em in VBScript.
The following expression should work for you, it will capture the portion of that file names you asked for:
"^[^_]+_(.*)\.dxf$"
If you need to edit the content of the .dxf files, you will need to work within the AutoCAD VBA (Visual Basic for Applications) environment.
If that is the case, you will need to start with something like below:
GetObject("AutoCAD.Application.20")
CreateObject("AutoCAD.Application.20")
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-ActiveX/files/GUID-0225808C-8C91-407B-990C-15AB966FFFA8-htm.html
** Please take note that "VBA is no longer distributed with the AutoCAD installation; it must be downloaded and installed separately. The VBA Enabler for Autodesk AutoCAD can be downloaded here."

Rename files using foldername as prefix and part of current filename VBS

I have a fairly unique situation and I'd like some insight. I have no programming background so I figured I'd turn here.
I have a bunch of folders. Inside each of those folders is another folder. Inside that folder is a few files.
These files are named with some gibberish letters and numbers, then the characters "-" (no quotes), and finally the name i'd like to use as the new suffix.
I would like to take that top tier foldername and make it the prefix and the above mentioned suffix to create "prefix - suffix" for each new filename.
My first thought was to do this via VBS, but again, I'm unfamiliar. Can someone shine some light or provide a script? Assuming its not too much of a hassle.
An example of what I have and what I'm looking for:
Give a try for this vbscript :
Option Explicit
Dim File,MyRootFolder,RootFolder,Prefix,Suffix
MyRootFolder = Browse4Folder
Call Scan4File(MyRootFolder)
MsgBox "Script Done !",VbInformation,"Script Done !"
'**************************************************************************
Function GetTheParent(DriveSpec)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
GetTheParent = fso.GetParentFolderName(Drivespec)
End Function
'**************************************************************************
Function StripPathFolder(Path)
Dim arrStr : arrStr = Split(Path,"\")
StripPathFolder = arrStr(UBound(arrStr))
End Function
'**************************************************************************
Function StripPathFile(Path)
Dim arrStr : arrStr = Split(Path,"-")
StripPathFile = Replace(arrStr(UBound(arrStr)),"_","-")
End Function
'**************************************************************************
Function Browse4Folder()
Dim objShell,objFolder,Message
Message = "Please select a folder in order to scan into it and its subfolders to rename files"
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder(0,Message,0,0)
If objFolder Is Nothing Then
Wscript.Quit
End If
Browse4Folder = objFolder.self.path
End Function
'**********************************************************************************************
Function Scan4File(Folder)
Dim fso,objFolder,arrSubfolders,File,SubFolder,NewFileName
Set fso = CreateObject("Scripting.FileSystemObject")
Set objFolder = fso.GetFolder(Folder)
Set arrSubfolders = objFolder.SubFolders
For Each File in objFolder.Files
RootFolder = GetTheParent(GetTheParent(File))
Prefix = StripPathFolder(RootFolder)
Suffix = StripPathFile(File)
NewFileName = Prefix & Suffix
'MsgBox Prefix,Vbinformation,Prefix
'MsgBox Suffix,Vbinformation,Suffix
'MsgBox "New File Name ==> " & NewFileName,Vbinformation,Prefix & Suffix
Call RenameFile(File,NewFileName)
Next
For Each SubFolder in objFolder.SubFolders
Call Scan4File(SubFolder)
Next
End Function
'**********************************************************************
Sub RenameFile(File1,File2)
Dim Ws,Command,Execution
Set Ws = CreateObject("WScript.Shell")
Command = "Cmd /c Ren "& DblQuote(File1) &" "& DblQuote(File2) &""
Execution = Ws.Run(Command,0,False)
End Sub
'**********************************************************************
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'**********************************************************************
This is a little startup (idea), just to rename for one file, so give a try and tell me is this as you expected to rename like this or not (for one file) ?
Option Explicit
Dim File,RootFolder,Prefix,Suffix
File = "aerzipjfdesh785zafokvsshjdj_-_File1"
RootFolder = GetTheParent("c:\FolderA\Folder_A")
Prefix = StripPathFolder(RootFolder)
Suffix = StripPathFile(File)
MsgBox Prefix,Vbinformation,Prefix
MsgBox Suffix,Vbinformation,Suffix
MsgBox "New File Name ==> " & Prefix & Suffix,Vbinformation,Prefix & Suffix
'**************************************************************************
Function GetTheParent(DriveSpec)
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
GetTheParent = fso.GetParentFolderName(Drivespec)
End Function
'**************************************************************************
Function StripPathFolder(Path)
Dim arrStr : arrStr = Split(Path,"\")
StripPathFolder = arrStr(UBound(arrStr))
End Function
'**************************************************************************
Function StripPathFile(Path)
Dim arrStr : arrStr = Split(Path,"-")
StripPathFile = Replace(arrStr(UBound(arrStr)),"_","-")
End Function
'**************************************************************************

Rename files without copying in same folder

I have files with following naming convention.
RE12356_GJ123456789.DAT
I need to rename the file to RE12356_GJ123456790.DAT without copying the files using VBS i.e. I need to increment by 1, everytime when I run VBS file. Please help me. Thanks!
The FileSystemObject has a method .GetFile(FileSpec) that returns an object for the file FileSpec. Those objects have a (writable) .Name property. So get the .Name, modify it, and write/assign the new one.
To give you some ideas (looping over the files in a folder, finding the file(s) to change, extracting the number to increment):
Option Explicit
Dim goFS : Set goFS = CreateObject( "Scripting.FileSystemObject" )
WScript.Quit demoMain()
Function demoMain()
demoMain = 0 ' assume success
Dim sDDir : sDDir = goFS.GetAbsolutePathName(".\")
Dim reVictim : Set reVictim = New RegExp
reVictim.IgnoreCase = True
reVictim.Pattern = "^(victim)(\d+)(\.txt)$"
Dim oFile
For Each oFile In goFS.GetFolder(sDDir).Files
If reVictim.Test(oFile.Name) Then
WScript.Echo "found: ", oFile.Name
oFile.Name = reVictim.Replace(oFile.Name, GetRef("FINC"))
WScript.Echo "renamed:", oFile.Name
End If
Next
End Function ' demoMain
Function FINC(sM, sG1, sG2, sG3, nP, sS)
FINC = sG1 & Right(100 + sG2 + 1, 2) & sG3
End Function
output:
cscript finc.vbs
found: victim00.txt
renamed: victim01.txt
cscript finc.vbs
found: victim01.txt
renamed: victim02.txt
cscript finc.vbs
found: victim02.txt
renamed: victim03.txt
How to copy with overflow of the counter is left as exercise.
You can just use the "move" command which will not actually rewrite the file but will just move the entry in the file table... which is essentially a "rename"
If you don't want to use filesystemobject.move you could issue a command line rename command via: Wsript.shell
like...
Dim objShell
Set objShell = WScript.CreateObject ("WScript.shell")
objShell.run "cmd /c rename somefile.txt newname.txt"
Set objShell = Nothing
or as Ekkehard.Horner pointed out:
Dim fso, f, s
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(filespec)
f.name = "newFileName.txt"
see: Name Property (FileSystemObject)

Resources