recursive file delete with api

I need to delete all files in a folder and all subfolders and their file.  I think It has to use the findfile API as the vb DIR function does not return hidden or system files.  Thus if a hidden file is in the folder it is never removed.  here is the current code im using

Public Sub RmTree(ByVal vDir As Variant)

'fully works but does not work for hidden files

    Dim vFile As Variant
    ' Check if "\" was placed at end
    ' If So, Remove it

    On Error Resume Next
   
    If Right(vDir, 1) = "\" Then
        vDir = Left(vDir, Len(vDir) - 1)
    End If


    ' Check if Directory is Valid
    ' If Not, Exit Sub
    vFile = Dir(vDir, vbDirectory)


    If vFile = "" Then
        Exit Sub
    End If


    ' Search For First File
    vFile = Dir(vDir & "\", vbDirectory)
    ' Loop Until All Files and Directories
    ' Have been Deleted

    Do Until vFile = ""

        If vFile = "." Or vFile = ".." Then
            vFile = Dir
        ElseIf (GetAttr(vDir & "\" & vFile) And _
            vbDirectory) = vbDirectory Then
            RmTree vDir & "\" & vFile
            vFile = Dir(vDir & "\", vbDirectory)
        Else
            SetAttr vDir & "\" & vFile, vbNormal
            Kill vDir & "\" & vFile
            vFile = Dir
        End If
    Loop

    ' Remove Top Most Directory except c:\temp
    If vDir <> "c:\temp" Then
       RmDir vDir
    End If
   
End Sub
ocsscottAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

twardCommented:
Try the following API Call, if you give it a folder name, it should delete the whole folder...  I have not tested it though....

Attribute VB_Name = "API_SHFileOperations"
Option Explicit

Public Const FO_COPY = &H2
Public Const FO_DELETE = &H3
Public Const FO_MOVE = &H1
Public Const FO_RENAME = &H4

Public Const FOF_ALLOWUNDO = &H40
Public Const FOF_CONFIRMMOUSE = &H2
Public Const FOF_FILESONLY = &H80                  '  on *.*, do only files
Public Const FOF_MULTIDESTFILES = &H1
Public Const FOF_NOCONFIRMATION = &H10             '  Don't prompt the user.
Public Const FOF_NOCONFIRMMKDIR = &H200            '  don't confirm making any needed dirs
Public Const FOF_RENAMEONCOLLISION = &H8
Public Const FOF_SILENT = &H4                      '  don't create progress/report
Public Const FOF_SIMPLEPROGRESS = &H100            '  means don't show names of files
Public Const FOF_WANTMAPPINGHANDLE = &H20          '  Fill in SHFILEOPSTRUCT.hNameMappings

Private Type SHFILEOPSTRUCT
       
       hwnd As Long
       wFunc As Long
       pFrom As String
       pTo As String
       fFlags As Integer
       fAnyOperationsAborted As Boolean
       hNameMappings As Long
       lpszProgressTitle As String
       
End Type

Private Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long

Public Const OF_CANCEL = &H800
Public Const OF_CREATE = &H1000
Public Const OF_DELETE = &H200
Public Const OF_EXIST = &H4000
Public Const OF_PARSE = &H100
Public Const OF_PROMPT = &H2000
Public Const OF_READ = &H0
Public Const OF_READWRITE = &H2
Public Const OF_REOPEN = &H8000
Public Const OF_SHARE_COMPAT = &H0
Public Const OF_SHARE_DENY_NONE = &H40
Public Const OF_SHARE_DENY_READ = &H30
Public Const OF_SHARE_DENY_WRITE = &H20
Public Const OF_SHARE_EXCLUSIVE = &H10
Public Const OF_VERIFY = &H400
Public Const OF_WRITE = &H1

Public Const OFS_MAXPATHNAME = 128

Public Type OFSTRUCT
       
      cBytes As Byte
      fFixedDisk As Byte
      nErrCode As Integer
      Reserved1 As Integer
      Reserved2 As Integer
      szPathName(OFS_MAXPATHNAME) As Byte
     
End Type

Public Declare Function OpenFile Lib "kernel32" (ByVal lpFileName As String, lpReOpenBuff As OFSTRUCT, ByVal wStyle As Long) As Long
Public Sub CopyThisFile(FileName As String, ToDir As String)

  On Error Resume Next
 
  Dim CopyError As Long
  Dim FileStruct As SHFILEOPSTRUCT
 
  If DoesFileExist(FileName) = True Then
   
    FileStruct.pFrom = FileName
    FileStruct.pTo = ToDir
    FileStruct.fFlags = FOF_NOCONFIRMMKDIR + FOF_NOCONFIRMATION + FOF_SILENT
    FileStruct.wFunc = FO_COPY
    CopyError = SHFileOperation(FileStruct)
   
  Else
   
    Err.Raise CopyError, "API_SHFileOperations.CopyThisFile", Err.Description
   
  End If
 
End Sub
Public Function DoesFileExist(NameOfFile As String) As Boolean
   
  DoesFileExist = True
 
'  Dim Buffer As OFSTRUCT
'
'  If (Len(NameOfFile) = 0) Or (InStr(NameOfFile, "*") > 0) Or (InStr(NameOfFile, "?") > 0) Then
'
'    DoesFileExist = False
'    Exit Function
'
'  End If
'
'  On Error GoTo NoSuchFile
'
'  If OpenFile(NameOfFile, Buffer, OF_EXIST) < 0 Then
'
'    GoTo CheckForError
'
'  Else
'
'    DoesFileExist = True
'    Exit Function
'
'  End If
'
'CheckForError:
'  If Buffer.nErrCode Then
'
'    GoTo NoSuchFile
'
'  End If
'
'NoSuchFile:
'  DoesFileExist = False
'
'ExitFileExist:
'  On Error GoTo 0

End Function
Public Sub DeleteThisFile(FileName As String)
 
  Dim DeleteError As Long
 
  Dim FileStruct As SHFILEOPSTRUCT
 
  On Error Resume Next
 
  If DoesFileExist(FileName) = True Then
   
    FileStruct.pFrom = FileName
    FileStruct.fFlags = FOF_SILENT + FOF_ALLOWUNDO + FOF_NOCONFIRMATION
    FileStruct.wFunc = FO_DELETE
    DeleteError = SHFileOperation(FileStruct)
   
  Else
   
    Err.Raise DeleteError, "API_SHFileOperations.DeleteThisFile", Err.Description
 
  End If
 
End Sub
Public Sub MoveThisFile(FileName As String, DestName As String)

  Dim MoveError As Long
  Dim FileStruct As SHFILEOPSTRUCT
 
  On Error Resume Next
 
  If DoesFileExist(FileName) = True Then
   
    FileStruct.pFrom = FileName
    FileStruct.pTo = DestName
     
    FileStruct.fFlags = FOF_SILENT + FOF_NOCONFIRMATION
    FileStruct.wFunc = FO_MOVE
    MoveError = SHFileOperation(FileStruct)
   
  Else
   
    Err.Raise MoveError, "API_SHFileOperations.MoveThisFile", Err.Description
 
  End If
 
End Sub
Public Sub RenameThisFile(FileName As String, Target As String)

  On Error Resume Next
 
  Dim RenameError As Long
  Dim FileStruct As SHFILEOPSTRUCT
 
  If DoesFileExist(FileName) = True Then
   
    FileStruct.pFrom = FileName
    FileStruct.pTo = Target
     
    FileStruct.fFlags = FOF_RENAMEONCOLLISION + FOF_SILENT
    FileStruct.wFunc = FO_RENAME
    RenameError = SHFileOperation(FileStruct)
 
  Else
   
    Err.Raise RenameError, "API_SHFileOperations.RenameThisFile", Err.Description
 
  End If
 
End Sub
0
ocsscottAuthor Commented:
I tried the SHO function and had problems, can't remember exactly but I really want to use the findfile api instead.
0
VbmasterCommented:
Here's a function that gives you all files inside a directory including subdirectories.

You use it with a call something like this..

  Dim x() As String
  Call ListFiles("C:\TheDir\", x(), True, True)

Then you can use a simple For..Next loop to iterate thru all files and delete 'em..

  For a = 1 To Ubound(x)
    Kill x(a)
  Next


Function ListFiles(ByVal Path As String, ByRef av_Array() As String, Recursive As Boolean, Optional IncludePaths As Boolean = True, Optional Prefix As String = "*.*", Optional ByRef x As Double = 0, Optional StartDir As Boolean = True)

  Dim MyName  As String
  Dim MyDir() As String
  Dim MyDirNr As Integer
  Dim a       As Integer
 
  MyDirNr = 0
  If StartDir Then
    x = 0
    Path = IIf(Right$(Path, 1) = "\", Path, Path & "\")
    Prefix = UCase$(Prefix)
  End If
 
  On Error GoTo Errorhandler
 
  MyName = Dir$(Path & "*.*", vbDirectory + vbArchive + vbHidden + vbReadOnly + vbSystem)
  Do While (Len(MyName) > 0)
    If (MyName <> ".") And (MyName <> "..") Then
      If (GetAttr(Path & MyName) And vbDirectory) = vbDirectory Then
        ReDim Preserve MyDir(MyDirNr + 1)
        MyDirNr = MyDirNr + 1
        MyDir(MyDirNr) = MyName
      Else 'If (UCase$(MyName) Like Prefix) Then
        If (x Mod 10 = 0) Then ReDim Preserve av_Array(x + 10)
        x = x + 1
        If IncludePaths Then
          av_Array(x) = Path & MyName
        Else
          av_Array(x) = MyName
        End If
      End If
    End If
    MyName = Dir$
  Loop
 
  If Recursive Then
    For a = 1 To MyDirNr
      If Not ListFiles(Path + MyDir(a) + "\", av_Array(), True, IncludePaths, Prefix, x, False) Then GoTo Errorhandler
    Next
  End If
  If StartDir Then ReDim Preserve av_Array(x)
  ListFiles = True
  Exit Function
 
Errorhandler:
  ListFiles = False

End Function
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ocsscottAuthor Commented:
well vbmaster i didnt actually use your code but it showed me the problem I used your

Dir$(Path & "*.*", vbDirectory + vbArchive + vbHidden + vbReadOnly + vbSystem)
 
code instead of just dir$ and now i can get to the system and hidden files.

thanks alot bud.   scott
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.