PDA

Показать полную графическую версию : [решено] WSH скрипт для удаления файлов (логика скрипта внутри)


Francyz
13-05-2010, 16:10
Есть скрипт для удаления пустых папок (взял из соседней темы)
strFldr = Wscript.arguments.Item(0)

Dim oD, cD, oI

Set objFSO = CreateObject("Scripting.FileSystemObject")
DelBlank strFldr

Sub DelBlank(sFldr)

Set oD = objFSO.GetFolder(sFldr)
Set cD = oD.SubFolders

For Each oI In cD
DelBlank oI.Path
Next

If oD.Size = 0 Then
wscript.echo OD + " - Folder delete"
oD.Attributes = 0
oD.Delete
else
wscript.echo OD + " - Folder is no Empty"
End If
End Sub

Но у меня проблема в его развитии дальше.

Логика скрипта на WSH такая:
1 - Нужен скрипт, который будет удалять файлы по маске (т.е. определенные типы файлы, которые занесены к примеру в тот же test.txt);
2 - Нужно задавать исключения на папки, которые будет пропускать (те же Windows, Programm Files и т.д., чтобы не стереть лишнее);
3 - Если файл занят - он его пропускает и движется дальше;
4 - Ну соответственно, если папки пустые - он их тоже удаляет;
5 - и последнее, чтобы он не трогал подключаемые диски (флешки, сетевые диски), а работал только с локальными (т.е. у которых значение DriveType==2 - это по-моему обозначение как раз-таки локальных);

Немного покопавшись в книгах нашел пару записей, к примеру по пункту 2, вот есть "Выполнение программа для всех подпапок":

Sub GoSubFolder (objDIR)
If objDIR <> "\System Volume Information" Then
MainSub objDIR
For Each eFolder in objDIR.SubFolders
GoSubFolders eFolder
Next
End If
End Sub

-т.е. получается он будет выполнять для всех папок, кроме указанной Volume. Я так понял, чтобы остальные не трогал нужно добавить в условие все папки, которые ты не хочешь использовать - по типу <> "\System Volume Information" or "\Windows" or "\Programm Files" и т.д.

Но прежде чем в какой-то папке выполнять он должен с ней соединиться, и получается вот такой код:

Function GetFolder(sFOLDER)
On Error Resume Next
Set GetFolder = FSO.GetFolder(sFOLDER)
If Err.Number <> 0 Then
Wscript.Echo "Error connecting to folder:" & sFOLDER & VBlf & "[" & Err.Number & "]" & Err.Description
Wscript.Quit Err.Number
End If
End Function


Для удаления файла используется подобный код

Sub DelFile(sFILE)
On Error Resume Next
FSO.Delete File sFILE, True
If Err.Number <> 0 Then
Wscript.Echo "Error deleting file: " & sFILE
End If
End sub



Вот чтобы удалить все файлы определенного типа, нужно выполнить:

Set FSO = CreateObject("Scripting.FileSystemObject")
sDIR = "directory"
sEXT = "EXT"

Set objDIR = GetFolder(sDIR)
GoSubFolders objDIR

Sub MainSub (objDIR)
For Each efile in obj.DIR.Files
fEXT = FSO.GetExtensionName(efile.Path)
If LCase(fEXT) = LCase(sEXT) Then
DelFile efile
End If
Next
End sub

где directory- те папки где искать файлы, а EXT - сами расширения файлов

Получается чтобы скрипт нормально работал нужно, сначала написать GoSubFolder , потом GetFolder, потом DelFile и после этого уже "Определение конкретного типа", но у меня не получается соединить это воедино, чтобы оно нормально работало, все время вылезает какая-нибудь ошибка и не получается разобраться с пунктами 3 и 5

Может у кого, есть уже подобные скрипты. Буду рад любой помощи.

amel27
14-05-2010, 11:45
Francyz, п.1-4 (шаблоны файлов/папок задаются регулярными выражениями (http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0 %BD%D0%B8%D1%8F)):
sFldr = Wscript.Arguments.Item(0)

' Шаблоны удаляемых файлов
' ------------------------
cInclFiles = Array( _
"\\~\$[^\\]+$", _
"\.(BAK|TMP|TEMP)$")

' Шаблоны пропускаемых каталогов
' ------------------------------
cExclFolders = Array( _
"^.:\\Documents and Settings$", _
"^.:\\Program Files$", _
"^.:\\System Volume Information$", _
"^.:\\WINDOWS$" )

' Компиляция шаблонов
' -------------------
RegExpComp cInclFiles
RegExpComp cExclFolders

Set objFSO = CreateObject("Scripting.FileSystemObject")

ClearDir sFldr, cInclFiles, cExclFolders

Sub ClearDir(sFldr, cIncl, cExcl)
On Error Resume Next
Dim oD, cF, cD, oI, iR

For iR=0 To UBound(cExcl)
If cExcl(iR).Test(sFldr) Then Exit Sub
Next

Set oD = objFSO.GetFolder(sFldr)
Set cF = oD.Files
Set cD = oD.SubFolders

For Each oI In cF
For iR=0 To UBound(cIncl)
If cIncl(iR).Test(oI.Path) Then
WScript.Echo "File : " & oI.Path
oI.Attributes = 0
oI.Delete
Exit For
End If
Next
Next

For Each oI In cD
ClearDir oI.Path, cIncl, cExcl
Next

If oD.Size >0 Then Exit Sub
WScript.Echo "Folder: " & oD.Path

oD.Attributes = 0
oD.Delete
End Sub

Sub RegExpComp(aReg)
Dim iReg, sReg

For iReg=0 To UBound(aReg)
sReg = aReg(iReg)
Set aReg(iReg) = CreateObject("VBScript.RegExp")
aReg(iReg).Pattern = sReg
aReg(iReg).IgnoreCase = True
Next
End Sub

Francyz
14-05-2010, 15:07
amel27, Большое спасибо, по поводу 5-го пункта есть вот такое условие:

For Each objDrive In objFSO.Drives ' Перебираем все существующие тома.
If objDrive.DriveType = 2 Then ' Том фиксированный?
If objDrive.IsReady Then ' Том готов?
WScript.Echo "Find on drive " & objDrive.DriveLetter & ":..." ' выдаем найденные диски

End If
End if
Next
Это условие проверяет все локальные диски и работает уже с ними. Т.е. как раз выполняется условие о локальных дискам и не затрагивает флешки и сетевые.

Можете подсказать, в каком месте его соединить с предложенным вами скриптом, чтобы убрать sFldr = Wscript.Arguments.Item(0) и я бы не вводил в CMD команду "Cscript testdel.vbs c:\", а просто ввел "Cscript testdel.vbs" и он уже тогда бы просканировал все найденные диски сам.

amel27
14-05-2010, 16:06
Francyz, заменить 24-ю строку (та, что после "Set objFSO = ...") на:
For Each objDrive In objFSO.Drives
If objDrive.DriveType=2 And objDrive.IsReady Then
ClearDir objDrive.DriveLetter, cInclFiles, cExclFolders
End if
Next

Francyz
15-05-2010, 11:08
amel27, Спасибо, добавил указанное условие и удалил вначале строчку sFldr = Wscript.Arguments.Item(0), чтобы не указывать диск самому, но ничего не происходит. Скрипт выполняется без ошибок, но никаких действий нет, я так понял из-за того, что не заменили переменную sFldr в остальных местах.

В указанном условии:

For Each objDrive In objFSO.Drives
If objDrive.DriveType=2 And objDrive.IsReady Then
ClearDir objDrive.DriveLetter, cInclFiles, cExclFolders
End if
Next


Мы заменили переменную sFldr на objDrive.DriveLetter:

было:
ClearDir sFldr, cInclFiles, cExclFolders

стало:
ClearDir objDrive.DriveLetter, cInclFiles, cExclFolders


Но в самой функции Sub ClearDir переменная sFldr осталась. я попытался заменить по аналогии на objDrive.DriveLetter, но результата так же не было, может я чего упустил, вот что получилось в итоге:

Dim objDrive

cInclFiles = Array( _
"\\~\$[^\\]+$", _
"\.(TXT|MP3)$")

cExclFolders = Array( _
"^.:\\Documents and Settings$", _
"^.:\\Program Files$", _
"^.:\\System Volume Information$", _
"^.:\\WINDOWS$" )

RegExpComp cInclFiles
RegExpComp cExclFolders

Set objFSO = CreateObject("Scripting.FileSystemObject")

For Each objDrive In objFSO.Drives
If objDrive.DriveType=2 And objDrive.IsReady Then
ClearDir objDrive.DriveLetter, cInclFiles, cExclFolders
End if
Next

Sub ClearDir(objDrive.DriveLetter, cIncl, cExcl)
On Error Resume Next
Dim oD, cF, cD, oI, iR

For iR=0 To UBound(cExcl)
If cExcl(iR).Test(objDrive.DriveLetter) Then Exit Sub
Next

Set oD = objFSO.GetFolder(objDrive.DriveLetter)
Set cF = oD.Files
Set cD = oD.SubFolders

For Each oI In cF
For iR=0 To UBound(cIncl)
If cIncl(iR).Test(oI.Path) Then
WScript.Echo "File : " & oI.Path
oI.Attributes = 0
oI.Delete
Exit For
End If
Next
Next

For Each oI In cD
ClearDir oI.Path, cIncl, cExcl
Next

If oD.Size >0 Then Exit Sub
WScript.Echo "Folder: " & oD.Path

oD.Attributes = 0
oD.Delete
End Sub

Sub RegExpComp(aReg)
Dim iReg, sReg

For iReg=0 To UBound(aReg)
sReg = aReg(iReg)
Set aReg(iReg) = CreateObject("VBScript.RegExp")
aReg(iReg).Pattern = sReg
aReg(iReg).IgnoreCase = True
Next
End Sub

amel27
15-05-2010, 13:16
в самой функции Sub ClearDir переменная sFldr осталась. я попытался заменить по аналогии на objDrive.DriveLetter, но результата так же не было, может я чего упустил »переменные в скрипте и в функции - это разные переменные, хоть и называются одинаково, так их менять ни в коем случае нельзя, ошибка была в другом - в букве диска objDrive.DriveLetter не хватало двоеточия:
cInclFiles = Array( _
"\\~\$[^\\]+$", _
"\.(TMP|BAK|TEMP)$")

cExclFolders = Array( _
"^.:\\Documents and Settings$", _
"^.:\\Program Files$", _
"^.:\\System Volume Information$", _
"^.:\\WINDOWS$" )

RegExpComp cInclFiles
RegExpComp cExclFolders

Set oFSO = CreateObject("Scripting.FileSystemObject")

For Each oDrive In oFSO.Drives
If oDrive.DriveType=2 And oDrive.IsReady Then
ClearDir oDrive.DriveLetter & ":", cInclFiles, cExclFolders
End If
Next

Sub ClearDir(sFldr, cIncl, cExcl)
On Error Resume Next
Dim oD, cF, cD, oI, iR

For iR=0 To UBound(cExcl)
If cExcl(iR).Test(sFldr) Then Exit Sub
Next

Set oD = oFSO.GetFolder(sFldr)
Set cF = oD.Files
Set cD = oD.SubFolders

For Each oI In cF
For iR=0 To UBound(cIncl)
If cIncl(iR).Test(oI.Path) Then
WScript.Echo "File : " & oI.Path
oI.Attributes = 0
oI.Delete
Exit For
End If
Next
Next

For Each oI In cD
ClearDir oI.Path, cIncl, cExcl
Next

If oD.Size >0 Then Exit Sub
WScript.Echo "Folder: " & oD.Path

oD.Attributes = 0
oD.Delete
End Sub

Sub RegExpComp(aReg)
Dim iReg, sReg

For iReg=0 To UBound(aReg)
sReg = aReg(iReg)
Set aReg(iReg) = CreateObject("VBScript.RegExp")
aReg(iReg).Pattern = sReg
aReg(iReg).IgnoreCase = True
Next
End Sub

Francyz
15-05-2010, 15:00
Большое спасибо, просто сбило с толку одинаковое название.

Francyz
17-05-2010, 15:27
У меня вот возник вопрос, а как можно в самих исключениях настройку сделать?
Вот добавлена папка "\\Documents and Settings$" ее трогать не нужно, поскольку там много всего, но нужно в ней почистить две папки юзера: Desktop (тобишь рабочий стол) и Мои документы (там где картинки и все прочее.). Так вот вопрос: "это можно как-то дописать к исключению или нужно просто добавить еще одну функцию ниже Sub ClearDir и в ней указать просто эти две папки"?

Вот есть код, для размещения ярлыка на рабочем столе, т.е. можно также считать путь к рабочему и удалить там (и по аналогии сделать для папки "Мои Документы")?
rem Читаем путь к Рабочему столу
DesktopPath = WSHShell.SpecialFolders("Desktop")

rem Создаем ярлык на Рабочем столе
Set MyShortcut = WSHShell.CreateShortcut(DesktopPath & _
"\Должностные.lnk")

amel27
17-05-2010, 17:17
У меня вот возник вопрос, а как можно в самих исключениях настройку сделать? »исключение из исключений?.. но это уже список включаемых папок, т.е. совсем другая задача

Вот есть код, для размещения ярлыка на рабочем столе, т.е. можно также считать путь к рабочему и удалить там (и по аналогии сделать для папки "Мои Документы")? »если не менять назначение функции, то где-то так (для Desktop):

cInclFiles = Array( _
"\\~\$[^\\]+$", _
"\.(TMP|BAK|TEMP)$")

cExclFolders = Array( _
"^.:\\Documents and Settings$", _
"^.:\\Program Files$", _
"^.:\\System Volume Information$", _
"^.:\\WINDOWS$" )

Set oFSO = CreateObject("Scripting.FileSystemObject")

For Each oDrive In oFSO.Drives
If oDrive.DriveType=2 And oDrive.IsReady Then
ClearDir oDrive.DriveLetter &":\", cInclFiles, cExclFolders
End If
Next

ClearDir WScript.CreateObject("WScript.Shell").SpecialFolders("Desktop"), _
cInclFiles, Array("^$")

Sub ClearDir(sFldr, cInclFiles, cExclFolders)
On Error Resume Next
Dim oD, cF, cD, oI, iR

If Not IsObject(cInclFiles(0)) Then RegExpComp cInclFiles
If Not IsObject(cExclFolders(0)) Then RegExpComp cExclFolders

For iR=0 To UBound(cExclFolders)
If cExclFolders(iR).Test(sFldr) Then Exit Sub
Next

Set oD = oFSO.GetFolder(sFldr)
Set cF = oD.Files
Set cD = oD.SubFolders

For Each oI In cF
For iR=0 To UBound(cInclFiles)
If cInclFiles(iR).Test(oI.Path) Then
WScript.Echo "File : " & oI.Path
oI.Attributes = 0
oI.Delete
Exit For
End If
Next
Next

For Each oI In cD
ClearDir oI.Path, cInclFiles, cExclFolders
Next

If oD.Size >0 Then Exit Sub
WScript.Echo "Folder: " & oD.Path

oD.Attributes = 0
oD.Delete
End Sub

Sub RegExpComp(ByRef aReg)
Dim iReg, sReg

For iReg=0 To UBound(aReg)
sReg = aReg(iReg)
Set aReg(iReg) = CreateObject("VBScript.RegExp")
aReg(iReg).Pattern = sReg
aReg(iReg).IgnoreCase = True
Next
End Sub

Francyz
18-05-2010, 10:41
Спасибо за пояснение.

Francyz
25-05-2010, 11:08
amel27, Добрый день. Сейчас обнаружил небольшой баг с исключениями. Я так понял они только в корне диска работают, а если данная папка находиться в подпапке, то он удаляет все данные в ней.
К примеру добавлена папка в исключения
"^.:\\Tester$", _

И скрипт пашет если вариант вот такой: "C:\\Tester", но если "C:\\Новая папка\Tester" и скрипт удаляет все файлы в ней. Я так понял что дело в символах перед наименованием папки ^.:\\ - они обозначают, как раз только букву диска, не распространясь на папки.

amel27
25-05-2010, 11:22
^.:\\ - они обозначают, как раз только букву диска, не распространясь на папки »
именно так, не зря же дал линк по регулярным выражениям, чтобы при необходимости меняли фильтры, любым папкам с именем "Tester" соответствует шаблон: "\\Tester$" ("^" - привязка шаблона к началу имени файла, "$" - к концу имени, "." - любой символ по аналогии с "?" в батниках)




© OSzone.net 2001-2012