I wrote this script to organize my video library. To keep consistent naming standards, I want a method to rename files in subfolders. The problem with the code below is that when I set fso = Nothing at the end, it breaks the FileSystemObject, and I cannot figure out a way to recall it with the standard For Each Next statement. In the meantime, I've turned it off, but if I step through all of the folders to rename, the appending numbers continue to ascend with each file regardless of folder. Ideally, this is the result I'm looking for:
(Let's use a TV Show as example)
Folder: Breaking Bad
Subfolder: Season 1
Files: Breaking S01E01, Breaking S01E02, Breaking S01E03
Subfolder: Season 2
Files: Breaking S02E01, Breaking S02E02, Breaking S02E03
Current results:
Folder: Breaking Bad
Subfolder: Season 1
Files: Breaking S01E01, Breaking S01E02, Breaking S01E03
Subfolder: Season 2
Files: Breaking S02E04, Breaking S02E05, Breaking S02E06
Note: I set up logging, so you can ignore all AddLog lines.
Option Explicit
Dim fso, oFolder, oFile, iCount, strSeries, strSeason, folder, fsoSubFolders, msg, objLogFile, strLogFile, sMsg
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFolder = fso.GetFolder(fso.GetAbsolutePathName("."))
Set fsoSubFolders = oFolder.SubFolders
strLogFile = oFolder & "\" & "Rename.log"
iCount = 0
CreateLogFile
AddLog(sMsg)
'CREATE LOG FILE ROUTINE
Sub CreateLogFile()
Set objLogFile = Nothing
If fso.FileExists(strLogFile) Then
Set objLogFile = fso.GetFile(strLogFile)
Set objLogFile = fso.OpenTextFile(strLogFile, 8, True)
AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
AddLog "|||||||||||||||||||||||||||||||||||||||||| NEW LOG FILE EVENT STARTED |||||||||||||||||||||||||||||||||||||||||||"
AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
AddLog "Preparing log file."
AddLog "Log File found."
AddLog "Appending to existing Log File: " & strLogFile
Else
Set objLogFile = fso.CreateTextFile(strLogFile)
objLogFile.Close
Set objLogFile = fso.OpenTextFile(strLogFile, 2, True)
AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
AddLog "|||||||||||||||||||||||||||||||||||||||||| NEW LOG FILE EVENT STARTED |||||||||||||||||||||||||||||||||||||||||||"
AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||"
AddLog "Preparing log file."
AddLog "Log File found not."
AddLog "Creating new Log File: " & strLogFile
End If
End Sub
'APPEND TO LOG ROUTINE
Sub AddLog(sMsg)
If Not ObjLogFile Is Nothing Then
If sMsg = "" Then
objLogFile.WriteLine(sMsg)
Else
objLogFile.WriteLine( Date & " - " & Time & ": " & "|" & sMsg)
End If
End If
End Sub
'SEARCH SUBFOLDERS
AddLog "||||||||||||||||||||||||||||||||||||||||||||||||| START SCRIPT ||||||||||||||||||||||||||||||||||||||||||||||||||"
For Each folder in fsoSubFolders
AddLog " "
AddLog "Working folder: " & folder
msg = MsgBox("CAUTION!" & vbCrLf & vbCrLf & _
"You are about to rename files in folder: " & folder.Name & ". " & _
"Do you want to continue?", vbYesNo, "Renaming Service")
If msg = vbYes Then
GetSeries
Else
AddLog "Skipping folder: " & folder
End If
Next
'GET SERIES NAME
Sub GetSeries()
strSeries = InputBox("ENTER SERIES NAME:" & vbCrlf & "(e.g.: Breaking Bad, The Walking Dead, Firefly, etc)", "Rename Series")
If strSeries = "" Then
AddLog "Exiting script before complete."
QuitApp()
ElseIf IsBlank(strSeries) = True Then
AddLog "ERROR: No value entered, restarting."
MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field cannot be blank. Try again."
GetSeries
ElseIf IsNumeric(strSeries) Then
AddLog "ERROR: Value cannot be numeric, restarting."
MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field does not support numeric values. Try again."
GetSeries
Else
AddLog "Series Title Set: " & strSeries
GetSeason
End If
End Sub
'GET SEASON NAME
Sub GetSeason()
strSeason = InputBox ("ENTER SEASON:" & vbCrlf & "(e.g.: 01, 02, 03, etc)", "Rename Season")
If strSeason = "" Then
AddLog "Exiting script before complete."
QuitApp()
ElseIf IsBlank(strSeason) = True Then
AddLog "ERROR: No value entered, restarting."
MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field cannot be blank. Try again."
GetSeries
ElseIf Not IsNumeric(strSeason) Then
AddLog "ERROR: Value cannot be non-numeric, restarting."
MsgBox "ERROR!" & vbCrLf & vbCrLf & "Field does not support non-numeric values. Try again."
GetSeason
Else
AddLog "Season Title Set: " & strSeason
AddLog "================================================================================================================="
Rename
End If
End Sub
'CHECK FOR BLANK VALUES
Function IsBlank(Value)
If IsEmpty(Value) or IsNull(Value) Then
IsBlank = True
ElseIf IsObject(Value) Then
If Value Is Nothing Then
IsBlank = True
End If
Else
IsBlank = False
End If
End Function
'RENAME FILES
Sub Rename()
For Each oFile In folder.Files
iCount = iCount + 1
If oFile.Name <> "Rename.vbs" Then
AddLog "Old file name: " & oFile.Name
If iCount = 1 Or iCount = 2 Or iCount = 3 Or iCount = 4 Or iCount = 5 Or iCount = 6 Or iCount = 7 Or iCount = 8 Or iCount = 9 Then
oFile.Name = strSeries & " S" & strSeason & "E0" & iCount & "." & fso.GetExtensionName(oFile.Name)
AddLog "New file name: " & oFile.Name
Else
oFile.Name = strSeries & " S" & strSeason & "E" & iCount & "." & fso.GetExtensionName(oFile.Name)
AddLog "New file name: " & oFile.Name
End If
End If
Next
Set oFile = Nothing
Set folder = Nothing
'Set fso = Nothing
End Sub
'PREMATURE QUIT
Sub QuitApp()
AddLog "|||||||||||||||||||||||||||||||||||||||||||||||||| END SCRIPT |||||||||||||||||||||||||||||||||||||||||||||||||||"
WScript.Quit()
End Sub
The file system object is needed for each access to your disk. Because of that you cannot set it to nothing as long as you still need to handle files. So in your case you can only set it to nothing at the end.
The reason why the numbering is wrong is a different one however.
Icount is a global variable and only set to 0 at the beginning of the script.
As within each season folder the episodes start at 1 again you also have to reset the icount whenever you enter one of these folders.
Set it to 0 at the first line of the rename function (before the for) and it should work.
One thing to keep in mind is that the folder.files will give you the current list of episodes sorted alphabetically. So your renaming will only work if the episodes are named in a format so they are in the right order when sorted alphabetically.
Related
I'm trying to copy all filenames list on the Recycle Bin in Windows 10.
I go to Command Prompt:
C:\>cd C:/$Recycle.Bin
C:\$Recycle.Bin>dir S-1-5-21-2370250818-2711005194-4184312249-1165
$R8CQG1I.txt
$IURO2ZD.txt
$RV2TEJ7.txt
I have 3 files I want to copy the real file names not the names like this result.
After some search I found this VBScript. I run the code and I get this error:
Expected end of statement
Option Explicit
DIM g_objWshShell, g_objFSO, g_sLogFile, g_objWshNetwork, g_sScriptName, g_sComputerName, g_sUserName Dim g_sVer, g_objLogFile, g_sLogDir
'Setup main variables and objects Set g_objWshShell = WScript.CreateObject("WScript.Shell") 'Create a Shell Object Set g_objFSO = CreateObject("Scripting.FileSystemObject") 'create a File System Object Set g_objWshNetwork = WScript.CreateObject("WScript.Network") 'Create Network Object g_sComputerName
= g_objWshNetwork.Computername 'Gets machine Computer name g_sUserName = g_objWshNetwork.UserName 'Gets logged-on username g_sScriptName=UCase(WScript.ScriptName) '
*** Name of the script
' *** START LogFile Information - use Delete or Append info below; don't use both *** Const FORREADING = 1, FORWRITING = 2, FORAPPENDING
= 8 'Setup constants for writing, appending, etc g_sLogDir = "C:\TEMP" If Not (g_objFSO.FolderExists(g_sLogDir)) Then g_objFSO.CreateFolder(g_sLogDir) End If g_sLogFile = g_sLogDir & "\" & Left(g_sScriptName,len(g_sScriptName)
- 3) & "LOG" 'Makes log file the SCRIPTNAME.Log g_sVer = "1.0"
'To delete a logfile and create a new one each time script is ran If g_objFSO.FileExists(g_sLogFile) Then g_objFSO.DeleteFile(g_sLogFile) 'Delete logfile if it exists. End If Set g_objLogFile = g_objFSO.CreateTextFile(g_sLogFile, FORWRITING) 'Setup the logfile for writing
Call Main() Call ExitScript()
'Start main script HERE *** Sub Main() Dim objRecycleBin, objFolderItems, objItem, strSpecialFolderName strSpecialFolderName = "Recycle Bin" 'Call WriteLine("Starting " & g_sScriptName & " at " & Date & " " & Time, g_objLogFile) Set objRecycleBin
= GetSpecialFolderObject(strSpecialFolderName) 'Get Special Folder based upon input name Set objFolderItems = objRecycleBin.Items() 'Get items within Recycle Bin For Each objItem In objFolderItems 'Delete all items within Special Folder If (objItem.Type = "File Folder") Then 'Check for file type g_objFSO.DeleteFolder(objItem.Path) 'Delete Folders Else g_objFSO.DeleteFile(objItem.Path) 'Delete Files End If WScript.Echo "Deleted " & objItem.Name Next End Sub
'*-*-*-*-*- Start Subroutines here
*-*-*-*-*- 'Returns SpecialFolder based upon name of folder Function GetSpecialFolderObject(NameOfFolder) Dim objShellApp, i, objSpecialFolder Set objShellApp = CreateObject("Shell.Application") On Error Resume Next For i=0 To 40 '40 is highest value for special folders Set objSpecialFolder = objShellApp.NameSpace(i) If (StrComp(objSpecialFolder.Title,NameOfFolder,vbTextCompare)=0) Then Set GetSpecialFolderObject = objSpecialFolder Exit For End If Next Err.Clear End Function
'Closes logfile and exits script Sub ExitScript() 'Call WriteLine(Date & " " & Time & "; Completed " & g_sScriptName, g_objLogFile) If IsObject(g_objLogFile) Then
g_objLogFile.Close End If Wscript.Quit End Sub
Sub EndOnError(sErrorString) WScript.Echo sErrorString & vbcrlf & "Check " & chr(34) & g_sLogFile & Chr(34) & " for details" Call WriteLine (sErrorString, g_objLogFile) WScript.Quit() End Sub
'Shows usage if input is wrong sub ShowUsage() WScript.Echo g_sScriptName & " v" & g_sVer & " Empties Recycle Bin for logged on user" & vbcrlf _ & vbcrlf & "USAGE: [CSCRIPT] " & g_sScriptName WScript.Quit end sub
'Writes to log Sub WriteLine(ByVal strMessage, ByVal objFile)
On Error Resume Next
If IsObject(objFile) then 'objFile should be a file object
objFile.WriteLine strMessage
Else
Call Wscript.Echo( strMessage )
End If End Sub
The VBScript version of #boxdog answer:
Set objShellApp = CreateObject("Shell.Application")
Set objSpecialFolder = objShellApp.NameSpace(10) '10 = Recyle Bin
For Each objFolder In objSpecialFolder.Items
WScript.Echo "FileName = " & objFolder.Name & vbTab & "Original Path = " & objFolder.ExtendedProperty("{9B174B33-40FF-11D2-A27E-00C04FC30871} 2")
Next
Answering this in case anyone is looking for VBS only solution.
In PowerShell, you can list the current path and original name/location of the Recycle Bin contents like This:
$shell = New-Object -ComObject Shell.Application
$shell.NameSpace(0x0a).Items() |
Select-Object #{Label="OriginalLocation";Expression={$_.ExtendedProperty("{9B174B33-40FF-11D2-A27E-00C04FC30871} 2")}},Name, Path
To copy the items, you can do this:
$shell.NameSpace(0x0a).Items() |
Copy-Item -Destination "C:\RecoveredFiles\$($_.Name)" -Recurse -Force
Note that this doesn't take into account any name-clashes - you'll need to test for that and adjust accordingly.
So I have two working .vbs scripts do two different things, one removes the read-only attribute in a file, and the other removes all files with ".v" extension. Both work when a folder is dropped on to the script.
I tried combining them, but with my limited knowledge I get a bunch of errors.
First code:
Option Explicit
Sub main()
Dim ArgCount
Dim filExt
ArgCount = WScript.Arguments.Count
Select Case ArgCount
Case 1 'Check the count of arguments
Dim FSO,Path,File,Num_1,Num_2
Set FSO = CreateObject("Scripting.FilesystemObject")
Path = WScript.Arguments(0)
If FSO.FileExists(Path) Then
Set File = FSO.GetFile(path)
If (File.Attributes Mod 2) = 1 Then 'Check if the Read-Only is selected, and remove it.
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & Path &" "& Err.Description
Else
MsgBox "Fjernelse fuldført"
End If
Else
MsgBox "The Read-Only attribute of file is not selected"
End If
Else
RemoveSubFolder Path,Num_1,Num_2
MsgBox Num_2 & " filer fuldført" & ", " & Num_1 & " filer fejlet"
End If
Case Else
MsgBox "Træk mappen oven på denne fil"
End Select
End Sub
'This function is to remove the Read-Only of all files in a folder and its subfolder
Function RemoveSubFolder(FolderPath,Num_1,Num_2)
Dim FSObject,Folder
Dim subFolder,File
Num_1 = 0
Num_2 = 0
Set FSObject = CreateObject("Scripting.FilesystemObject")
Set Folder = FSObject.GetFolder(FolderPath)
For Each subFolder In Folder.SubFolders 'Loop the subfolder in the folder
FolderPath = subFolder.Path
RemoveSubFolder FolderPath,Num_1,Num_2
Next
For Each File In Folder.Files 'Remove the Read-Only attribute of files in the folder
If (File.Attributes Mod 2) = 1 Then
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & File.Path &" "& Err.Description
Num_1 = Num_1 + 1
Else
Num_2 = Num_2 + 1
End If
End If
Err.Clear
Next
Set FSObject = Nothing
End Function
Call main
The second code is this:
Option Explicit
Dim FSObject, Folder, File, subFolder
Set FSObject = CreateObject("Scripting.FileSystemObject")
' Get the folder dropped onto our script...
Folder = WScript.Arguments(0)
' Recursively check each file with the folder and its subfolders...
DoFolder Folder
Sub DoFolder(Folder)
' Check each file...
For Each File In FSObject.GetFolder(Folder).Files
If Right(File.name, 2) = ".v" Then
FSObject.DeleteFile(Folder & "\" & File.name)
End If
Next
' Recursively check each subfolder...
For Each subFolder In FSObject.GetFolder(Folder).SubFolders
DoFolder subFolder.Path
Next
End Sub
Now, I tried combining them, but get a Syntax error on line 34
Option Explicit
Sub main()
Dim ArgCount
Dim filExt
ArgCount = WScript.Arguments.Count
Select Case ArgCount
Case 1 'Check the count of arguments
Dim FSO,Path,File,Num_1,Num_2
Set FSO = CreateObject("Scripting.FilesystemObject")
Path = WScript.Arguments(0)
If FSO.FileExists(Path) Then
Set File = FSO.GetFile(path)
If (File.Attributes Mod 2) = 1 Then 'Check if the Read-Only is selected, and remove it.
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & Path &" "& Err.Description
Else
MsgBox "Fjernelse fuldført"
End If
Else
MsgBox "The Read-Only attribute of file is not selected"
End If
Else
RemoveSubFolder Path,Num_1,Num_2
MsgBox Num_2 & " filer fuldført" & ", " & Num_1 & " filer fejlet"
End If
Case Else
MsgBox "Træk mappen oven på denne fil"
End Select
'This function is to remove the Read-Only of all files in a folder and its subfolder
Function RemoveSubFolder(FolderPath,Num_1,Num_2)
Dim FSObject,Folder
Dim subFolder,File
Num_1 = 0
Num_2 = 0
Set FSObject = CreateObject("Scripting.FilesystemObject")
Set Folder = FSObject.GetFolder(FolderPath)
For Each subFolder In Folder.SubFolders 'Loop the subfolder in the folder
FolderPath = subFolder.Path
RemoveSubFolder FolderPath,Num_1,Num_2
Next
For Each File In Folder.Files 'Remove the Read-Only attribute of files in the folder
If (File.Attributes Mod 2) = 1 Then
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & File.Path &" "& Err.Description
Num_1 = Num_1 + 1
Else
Num_2 = Num_2 + 1
End If
End If
Err.Clear
Next
' Recursively check each file with the folder and its subfolders...
DoFolder Folder
Sub DoFolder(Folder)
' Check each file...
For Each File In FSObject.GetFolder(Folder).Files
If Right(File.name, 2) = ".v" Then
FSObject.DeleteFile(Folder & "\" & File.name)
End If
Next
' Recursively check each subfolder...
For Each subFolder In FSObject.GetFolder(Folder).SubFolders
DoFolder subFolder.Path
Next
End Sub
Set FSObject = Nothing
End Function
Call main
They just don't work together, so how would I go about combining them?
UPDATE: I get this error with this code:
Option Explicit
Sub main()
Dim ArgCount
Dim filExt
ArgCount = WScript.Arguments.Count
Select Case ArgCount
Case 1 'Check the count of arguments
Dim FSO,Path,File,Num_1,Num_2
Set FSO = CreateObject("Scripting.FilesystemObject")
Path = WScript.Arguments(0)
If FSO.FileExists(Path) Then
Set File = FSO.GetFile(path)
If (File.Attributes Mod 2) = 1 Then 'Check if the Read-Only is selected, and remove it.
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & Path &" "& Err.Description
Else
MsgBox "Fjernelse fuldført"
End If
Else
MsgBox "The Read-Only attribute of file is not selected"
End If
Else
RemoveSubFolder Path,Num_1,Num_2
MsgBox Num_2 & " filer fuldført" & ", " & Num_1 & " filer fejlet"
End If
Case Else
MsgBox "Træk mappen oven på denne fil"
End Select
End Sub
'This function is to remove the Read-Only of all files in a folder and its subfolder
Function RemoveSubFolder(FolderPath,Num_1,Num_2)
Dim FSObject,Folder
Dim subFolder,File
Num_1 = 0
Num_2 = 0
Set FSObject = CreateObject("Scripting.FilesystemObject")
Set Folder = FSObject.GetFolder(FolderPath)
For Each subFolder In Folder.SubFolders 'Loop the subfolder in the folder
FolderPath = subFolder.Path
RemoveSubFolder FolderPath,Num_1,Num_2
Next
For Each File In Folder.Files 'Remove the Read-Only attribute of files in the folder
If (File.Attributes Mod 2) = 1 Then
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & File.Path &" "& Err.Description
Num_1 = Num_1 + 1
Else
Num_2 = Num_2 + 1
End If
End If
Err.Clear
Next
' Recursively check each file with the folder and its subfolders...
DoFolder Folder
Sub DoFolder(Folder)
' Check each file...
For Each File In FSObject.GetFolder(Folder).Files
If Right(File.name, 2) = ".v" Then
FSObject.DeleteFile(Folder & "\" & File.name)
End If
Next
' Recursively check each subfolder...
For Each subFolder In FSObject.GetFolder(Folder).SubFolders
DoFolder subFolder.Path
Next
End Sub
Set FSObject = Nothing
End Function
Call main
UPDATED CODE:
Option Explicit
Sub main()
Dim ArgCount
Dim filExt,Num_1,Num_2
ArgCount = WScript.Arguments.Count
Select Case ArgCount
Case 1 'Check the count of arguments
Dim FSO,Path,File,Num_1,Num_2
Set FSO = CreateObject("Scripting.FilesystemObject")
Path = WScript.Arguments(0)
If FSO.FileExists(Path) Then
Set File = FSO.GetFile(path)
If (File.Attributes Mod 2) = 1 Then 'Check if the Read-Only is selected, and remove it.
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & Path &" "& Err.Description
Else
MsgBox "Fjernelse fuldført"
End If
Else
MsgBox "The Read-Only attribute of file is not selected"
End If
Else
RemoveSubFolder Path,Num_1,Num_2
MsgBox Num_2 & " filer fuldført" & ", " & Num_1 & " filer fejlet"
End If
Case Else
MsgBox "Træk mappen oven på denne fil"
End Select
End Sub
'This function is to remove the Read-Only of all files in a folder and its subfolder
Dim FSObject,Folder
Dim subFolder,File
Num_1 = 0
Num_2 = 0
Set FSObject = CreateObject("Scripting.FilesystemObject")
Set Folder = FSObject.GetFolder(FolderPath)
For Each subFolder In Folder.SubFolders 'Loop the subfolder in the folder
FolderPath = subFolder.Path
RemoveSubFolder FolderPath,Num_1,Num_2
Next
For Each File In Folder.Files 'Remove the Read-Only attribute of files in the folder
If (File.Attributes Mod 2) = 1 Then
File.Attributes = File.Attributes-1
If Err.Number <> 0 Then
MsgBox "Error :" & File.Path &" "& Err.Description
Num_1 = Num_1 + 1
Else
Num_2 = Num_2 + 1
End If
End If
Err.Clear
Next
' Recursively check each file with the folder and its subfolders...
DoFolder Folder
Sub DoFolder(Folder)
' Check each file...
For Each File In FSObject.GetFolder(Folder).Files
If Right(File.name, 2) = ".v" Then
FSObject.DeleteFile(Folder & "\" & File.name)
End If
Next
' Recursively check each subfolder...
For Each subFolder In FSObject.GetFolder(Folder).SubFolders
DoFolder subFolder.Path
Next
End Sub
Function RemoveSubFolder(FolderPath, Num_1, Num_2)
Set FSObject = Nothing
End Function
Call main
I get this error now:
https://i.imgur.com/TDfgvLI.png
EDIT: After removing Num_1 and Num_2 definition in line 9, I get this error:
https://i.imgur.com/uEfkGCh.png
VBScript doesn't allow nesting procedure or function defintions insode other procedures or functions. Move the definition of DoFolder outside the function RemoveSubFolder.
Sub DoFolder(Folder)
'Check each file...
For Each File In FSObject.GetFolder(Folder).Files
If Right(File.Name, 2) = ".v" Then
FSObject.DeleteFile(Folder & "\" & File.Name)
End If
Next
'Recursively check each subfolder...
For Each subFolder In FSObject.GetFolder(Folder).SubFolders
DoFolder subFolder.Path
Next
End Sub
Function RemoveSubFolder(FolderPath, Num_1, Num_2)
...
End Function
My script is basically the same as last time, but there are some bonus features I'm having problems with.
Is there something similar to exception handling in VBScript? I've read about it and I'm not to sure and is there a way if the script gets canceled for not existing path folders, to create them and continue/restart?
Is there a way how I'm able to skip (They've to be there, but it would be fancy if I could be able to skip them.) at the beginning of the script all these text messages and how is it done?
Here's the code I've got so far:
Set fso = CreateObject("Scripting.FileSystemObject")
Function Pad(s)
Pad = Right("00" & s, 2)
End Function
Sub CopyFiles(fldr, dst)
'Copy all files from fldr to destination folder and append the date (in ISO
'format) to the name. Overwrite existing files.
For Each f In fldr.Files
created = Year(f.DateCreated) & "-" & Pad(Month(f.DateCreated)) & "-" & _
Pad(Day(f.DateCreated)) & "_" & Pad(Hour(f.DateCreated)) & _
Pad(Minute(f.DateCreated)) & Pad(Second(f.DateCreated))
newname = fso.GetBaseName(f) & "_" & created & "." & fso.GetExtensionName(f)
WScript.Echo "Aktuelles File, welches gerade kopiert wird: " & newname
f.Copy fso.BuildPath(dst, newname), True
Next
'Recurse into subfolders.
For Each sf In fldr.SubFolders
CopyFiles sf, dst
Next
End Sub
CopyFiles fso.GetFolder("C:\test"), "C:\test1"
How do I have to implement "On Error Resume Next"?
I've done something like this right now and I'm not to sure if it's correct:
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists("C:\test") Then
On Error Goto 0
Dim StartFolder, TargetFolder
StartFolder = "C:\test"
TargetFolder = "C:\test1"
Function Pad(s)
Pad = Right("00" & s, 2)
End Function
Sub CopyFiles(fldr, dst)
'Copy all files from fldr to destination folder and append the date (in ISO
'format) to the name. Overwrite existing files.
For Each f In fldr.Files
created = Year(f.DateCreated) & "-" & Pad(Month(f.DateCreated)) & "-" & _
Pad(Day(f.DateCreated)) & "_" & Pad(Hour(f.DateCreated)) & Pad(Minute(f.DateCreated)) & Pad(Second(f.DateCreated))
newname = fso.GetBaseName(f) & "_" & created & "." & fso.GetExtensionName(f)
If UCase(FSO.GetExtensionName(f.name)) = "JPG" Then
f.Copy fso.BuildPath(dst, newname), True
WScript.Echo "Ich kopiere: " & StartFolder & "\" & f.name & " nach " & TargetFolder & "\" & newname
End If
Next
'Recurse into subfolders.
For Each sf In fldr.SubFolders
CopyFiles sf, dst
Next
End Sub
CopyFiles fso.GetFolder("C:\test"), "C:\test1"
End If
On Error Resume Next
f.Copy fso.BuildPath(dst, newname), True
If Err Then
WScript.Echo Err.Description & " [0x" & Hex(Err.Number) & "]"
End If
On Error Goto 0
If I understood your question correctly, error handling should not be required for what you're trying to do. To make sure that a folder exists before doing something with it, you can simply use the FolderExists method:
If fso.FolderExists("C:\some\folder") Then
'do stuff
End If
However, if for some reason you must use error handling, it can be enabled with the statement On Error Resume Next and disabled with the statement On Error Goto 0. While error handling is enabled you can detect errors by checking the state of the Err object.
A very simple error handling routine might look like this:
On Error Resume Next
f.Copy fso.BuildPath(dst, newname), True
If Err Then
WScript.Echo Err.Description & " [0x" & Hex(Err.Number) & "]"
End If
On Error Goto 0
Error handling suppresses all runtime error messages, so you should keep it as local as possible. Having error handling enabled on a broader scope bears the risk of errors going unnoticed, causing unexpected/undesired behavior for instance due to variables being not initialized or retaining an obsolete value.
If you have several subsequent statements that could fail make sure you add error handling routines for each and clear the Err object after each statement:
On Error Resume Next
Set wmi = GetObject("winmgmts://./root/cimv2")
If Err Then
WScript.Echo Err.Description & " [0x" & Hex(Err.Number) & "]"
End If
Err.Clear
Set proc = wmi.ExecQuery("SELECT * FROM Win32_Process")
If Err Then
WScript.Echo Err.Description & " [0x" & Hex(Err.Number) & "]"
End If
Err.Clear
'...
On Error Goto 0
I tried with this link
copy files between a specified date range
but i am able to copying only root directory
please any one help me
Here you go. Please note that this can potentially create empty directories because it will create a directory and then check to see if each file falls within the specified date range or not. If no files do, the directory will remain empty.
Obviously, you can comment out or delete the WScript.Echo lines. They are for troubleshooting only.
Option Explicit
dim objFSO, strSource, strTarget
set objFSO = CreateObject("Scripting.FileSystemObject")
strSource = "c:\Folder1\"
strTarget = "c:\Copy of Folder1\"
call RecurseCopy(strSource, strTarget, True, #04/15/2012 00:00:01 AM#, #04/16/2012 00:00:01 AM#)
' // Recursively copy all files and folders
Sub RecurseCopy(strSource, strTarget, blnCopySubfolders, dBeginDate, dEndDate)
dim objSource, objTarget
WScript.Echo "Begin RecurseCopy" & vbcrlf & vbcrlf & _
"strSource: " & strSource & vbcrlf & _
"strTarget: " & strTarget
set objSource = objFSO.GetFolder(strSource)
If objFSO.FolderExists(strTarget) = False Then
Wscript.Echo "Now going to create folder: " & strTarget
objFSO.CreateFolder(strTarget)
End If
set objTarget = objFSO.GetFolder(strTarget)
Dim file
for each file in objSource.files
If file.DateCreated => dBeginDate AND file.DateCreated =< dEndDate Then
Wscript.Echo "Copying file: " & file.path & " to " & objTarget.Path
file.Copy objTarget.Path & "\" & file.name
Else
WScript.Echo "File will not be copied because the DateCreated is not within the specified range." & vbcrlf & vbcrlf & _
File.Path & " " & file.DateCreated
End If
next
If blnCopySubfolders = True Then
' ** For each subfolder of current dir, copy files to target and recurse its subdirs
Dim subdir
for each subdir in objSource.subfolders
call RecurseCopy(objSource.Path & "\" & subdir.Name, objTarget.Path & "\" & subdir.Name, True, dBeginDate, dEndDate)
Next
End If
End Sub
Below is the VBScript code. If the file/s or folder exist I get scripting error, "File already exists".
How to fix that?
How to create folder only if it does not exist and copy files only that are new or do not exist in source path?
How to insert the username (Point 1) after "Welcome" and at (Poin 3) instead of user cancelled?
Can the buttons be changed to Copy,Update,Cancel instead of Yes,No,Cancel? (Point 2)
The code:
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set wshShell = WScript.CreateObject( "WScript.Shell" )
strUserName = wshShell.ExpandEnvironmentStrings( "%USERNAME%" )
Message = " Welcome to the AVG Update Module" & vbCR '1*
Message = Message & " *****************************" & vbCR & vbCR
Message = Message & " Click Yes to Copy Definition Files" & vbCR & vbCR
Message = Message & " OR " & vbCR & vbCR
Message = Message & " Click No to Update Definition Files." & vbCR & vbCR
Message = Message & " Click Cancel (ESC) to Exit." & vbCR & vbCR
X = MsgBox(Message, vbYesNoCancel, "AVG Update Module") '2*
'Yes Selected Script
If X = 6 then
objFSO.FolderExists("E:\Updates")
if TRUE then objFSO.CreateFolder ("E:\Updates")
objFSO.CopyFile "c:\Docume~1\alluse~1\applic~1\avg8\update\download\*.*",
"E:\Updates\" , OverwriteFiles
MsgBox "Files Copied Succesfully.", vbInformation, "Copy Success"
End If
'No Selected Script
If X = 7 then
objFSO.FolderExists("Updates")
if TRUE then objFSO.CreateFolder("Updates")
objFSO.CopyFile "E:\Updates\*.*", "Updates", OverwriteFiles
Message = "Files Updated Successfully." & vbCR & vbCR
Message = Message & "Click OK to Launch AVG GUI." & vbCR & vbCR
Message = Message & "Click Cancel (ESC) to Exit." & vbCR & vbCR
Y = MsgBox(Message, vbOKCancel, "Update Success")
If Y = 1 then
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Progra~1\avg\avg8\avgui.exe" & Chr(34), 0
Set WshShell = Nothing
End if
If Y = 3 then WScript.Quit
End IF
'Cancel Selection Script
If X = 2 then
MsgBox "No Files have been Copied/Updated.", vbExclamation, "User Cancelled" '3*
End if
How to create folder only if it does not exist
This your code:
objFSO.FolderExists("E:\Updates")
if TRUE then objFSO.CreateFolder ("E:\Updates")
simply calls the FolderExists and CreateFolder methods in sequence (CreateFolder is always called because the if TRUE condition evaluates to True) and is equal to:
objFSO.FolderExists("E:\Updates")
objFSO.CreateFolder ("E:\Updates")
You want to call CreateFolder depending on the return value of the FolderExists method:
If Not objFSO.FolderExists("E:\Updates") Then
objFSO.CreateFolder "E:\Updates"
and copy files only that are new or do not exist in source path?
Neither VBScript nor the FileSystemObject object have this functionality. However, it is possible to call an external tool that can do that, such as xcopy, from your script using the WshShell.Run method. I guess you need something like this:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "xcopy c:\Docume~1\alluse~1\applic~1\avg8\update\download\*.* E:\Updates\ /D", , True
How to insert the username (Point 1)
Concatenate the message text with the strUserName variable value:
Message = " Welcome " & strUserName & " to the AVG Update Module" & vbCR
...
MsgBox "No Files have been Copied/Updated.", vbExclamation, strUserName & " Cancelled"
Can the buttons be changed to Copy,Update,Cancel Instead of Yes,No,Cancel?(Point 2)
No, VBScript's built-in MsgBox function does not support custom buttons. There're workarounds though: you could create your custom message box using an HTA (HTML application) or use the InputBox function to prompt the user for the task they wish to perform. You can find examples here.
I'd also like to note that you can improve your script by using the Select Case statement to check the MsgBox return value instead of multiple If...Then...End If statements. Also, it's a bad practice to use "magic numbers" like 6 or 7 - use the appropriate constants instead. For example:
Select Case X
Case vbYes
...
Case vbNo
...
Case Else ' vbCancel
...
End Select
When you say
"copy files only that are new or do
not exist in source path?"
do you mean you only want to copy files from the source directory to the destination directory if they do not exist in the destination? If so this will accomplish that
Const SourceFolder = "C:\Test1\"
Const DestinationFolder = "C:\Test2\"
Set fso = CreateObject("Scripting.FileSystemObject")
'Get a collection of al the files in the source directory
Set fileCol = fso.GetFolder(SourceFolder).Files
'Loop through each file and check to see if it exists in the destination directory
For Each objFile in fileCol
If NOT fso.FileExists(DestinationFolder & objFile.Name) Then
'If the file does not exist in the destination directory copy it there.
objFile.Copy DestinationFolder
Else
If objFile.DateLastModified > fso.GetFile(DestinationFolder & objFile.Name).DateLastModified Then
'If the file is newer than the destination file copy it there
objFile.Copy DestinationFolder, True
End If
End If
Next
Set fileCol = Nothing
Set fso = Nothing
Added the requested date check.