Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] WSH скрипт для удаления файлов (логика скрипта внутри) (http://forum.oszone.net/showthread.php?t=175586)

Francyz 13-05-2010 16:10 1412437

WSH скрипт для удаления файлов (логика скрипта внутри)
 
Есть скрипт для удаления пустых папок (взял из соседней темы)
Код:

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 1413087

Francyz, п.1-4 (шаблоны файлов/папок задаются регулярными выражениями):
Код:

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 1413241

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 1413289

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 1413757

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 1413808

Цитата:

Цитата Francyz
в самой функции 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 1413854

Большое спасибо, просто сбило с толку одинаковое название.

Francyz 17-05-2010 15:27 1415172

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

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

rem Читаем путь к Рабочему столу
DesktopPath = WSHShell.SpecialFolders("Desktop")

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


amel27 17-05-2010 17:17 1415237

Цитата:

Цитата Francyz
У меня вот возник вопрос, а как можно в самих исключениях настройку сделать? »

исключение из исключений?.. но это уже список включаемых папок, т.е. совсем другая задача

Цитата:

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

если не менять назначение функции, то где-то так (для 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 1415847

Спасибо за пояснение.

Francyz 25-05-2010 11:08 1420598

amel27, Добрый день. Сейчас обнаружил небольшой баг с исключениями. Я так понял они только в корне диска работают, а если данная папка находиться в подпапке, то он удаляет все данные в ней.
К примеру добавлена папка в исключения
Код:

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

amel27 25-05-2010 11:22 1420607

Цитата:

Цитата Francyz
^.:\\ - они обозначают, как раз только букву диска, не распространясь на папки »

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


Время: 19:42.

Время: 19:42.
© OSzone.net 2001-