Recursive scan skipping over accessible files and folders
Please skip to the last reply.
Below my code works fine when I choose a folder with no restrictions, but when I want to log unrestricted files of the entire C drive I get:
UnauthorizedAccessException was unhandled by user code
Access to the path 'C:\$RECYCLE.BIN\S-1-5-18\' is denied.
How can I get around this, catching this exception so my app doesn't crash on Recycle.Bin, but skips over it as well as other restricted folders, restricted subfolders, and restricted files?
Code:
Option Strict On
Imports System.IO
Public Class Form1
Private Dir As String
Dim FileExt As String
Dim FilePath As String
Dim Filename As String
Dim Items As New List(Of ListViewItem)
Dim Item As ListViewItem
Dim i2 As Integer = 0
Dim message As String
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.CenterToScreen()
End Sub
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
Dim height As Integer = Me.Height
If WindowState = FormWindowState.Maximized Then
Me.Width = SystemInformation.VirtualScreen.Width
Me.Height = height
ListView1.Width = Me.Width - 40
ListView1.Height = Me.Height - 130
Else
End If
Me.CenterToScreen()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListView1.Items.Clear()
Items.Clear()
Dim i As Integer = 0
Dir = New String(CType(FolderBrowserDialog1.SelectedPath, Char()))
If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then
Dir = New String(CType(FolderBrowserDialog1.SelectedPath, Char()))
Label1.Text = Dir
ListView1.Items.Clear()
End If
BackgroundWorker1.RunWorkerAsync()
End Sub
'label2 delegate
Delegate Sub SetLabelTextInvoker(ByVal label As Label, ByVal Text As String)
Sub SetLabelText(ByVal Label As Label, ByVal Text As String)
If Label2.InvokeRequired = True Then
Label2.Invoke(New SetLabelTextInvoker(AddressOf SetLabelText), Label, Text)
Else
Label2.Text = Text
End If
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
For i As Integer = 0 To i
For Each files As String In Directory.EnumerateFiles(Dir, "*.*", SearchOption.AllDirectories)
FileExt = New String(CType(IO.Path.GetExtension(files.ToLower), Char()))
FilePath = New String(CType(IO.Path.GetDirectoryName(files), Char()))
Filename = New String(CType(IO.Path.GetFileNameWithoutExtension(files), Char()))
Dim maxThreads As String = Nothing
Dim randomc As String
If maxThreads Is Nothing Then
Dim fExt As String = StrConv(FileExt, VbStrConv.ProperCase)
randomc = fExt.Trim(CChar(".")).ToUpper & " "
If randomc = " " Then
randomc = "Unknown"
Else
End If
maxThreads = randomc
End If
Dim sizeInBytes As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(files)
Dim separators() As String = {"*", ","}
Dim filesize As String = CStr(sizeInBytes.Length / 1024)
Dim input As String() = filesize.Split(separators, StringSplitOptions.RemoveEmptyEntries)
filesize = input(0)
Item = New ListViewItem
Item.Text = Filename & FileExt
Item.SubItems.Add(maxThreads)
Item.SubItems.Add(filesize & " KB")
Item.SubItems.Add(FilePath)
Items.Add(Item)
BackgroundWorker1.ReportProgress(i)
i2 = i
i = i + 1
If i = 1 Then
SetLabelText(Label2, CStr(i) + " file")
Else
SetLabelText(Label2, CStr(i) + " files")
End If
Next
If i > i2 Then
If i = 1 Then
message = "done"
BackgroundWorker1.ReportProgress(i)
i = 0
Else
message = "done"
BackgroundWorker1.ReportProgress(i)
i = 0
End If
Else
End If
Next
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
If message = "done" Then
ListView1.BeginUpdate()
ListView1.ListViewItemSorter = Nothing
ListView1.Items.AddRange(Items.ToArray)
'ListView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)
ListView1.Sort()
ListView1.EndUpdate()
message = ""
Else
End If
Label2.Refresh()
End Sub
End Class
Last edited by Peter Porter; May 5th, 2018 at 05:33 AM.
Re: Help logging accessible files, skipping all restricted folders & restricted files
You cannot use this:
Code:
For Each files As String In Directory.EnumerateFiles(Dir, "*.*", SearchOption.AllDirectories)
You need to build your own recursive file search that gets files and subfolders one level at a time. That way, you can wrap the Directory.GetFiles or Directory.EnumerateFiles call in a Try block and catch any exceptions thrown on that call specifically and still carry on searching more folders.
Re: Help logging accessible files, skipping all restricted folders & restricted files
jmcilhinney, I've been running on fumes the last few days.
Originally Posted by jmcilhinney
By the way, how does this make sense:
Code:
For i As Integer = 0 To i
Don't know what I was thinking when I coded that above.
Anyway, I've slapped together my own recursive search. I knew I had to get the directory first and catch exceptions while it searched for files, just couldn't concentrate while struggling to keep my eyes open.
The code below is sloppy, but it works. I'll clean it up after some rest.
Uses 1 button, 1 label, 2 listboxes and a FolderBrowserDialog.
Code:
Imports System.IO
Public Class Form1
Private Dir As String
Dim FileExt As String
Dim FilePath As String
Dim Filename As String
Dim Items As New List(Of ListViewItem)
Dim Item As ListViewItem
Dim i As Integer = 0
Dim i2 As Integer = 0
Dim i3 As Integer = 0
Dim message As String
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
i2 = 0
i3 = 0
Dir = New String(CType(FolderBrowserDialog1.SelectedPath, Char()))
'FolderBrowserDialog
If (FolderBrowserDialog1.ShowDialog() = DialogResult.OK) Then
Dir = New String(CType(FolderBrowserDialog1.SelectedPath, Char()))
ListBox1.Items.Clear()
ListBox2.Items.Clear()
End If
'Add folders to listbox1
For Each Folder As String In _
My.Computer.FileSystem.GetDirectories(Dir)
ListBox1.Items.Add(Folder)
Next
Try
For Each files As String In Directory.EnumerateFiles(Dir, "*.*", SearchOption.TopDirectoryOnly)
FileExt = New String(CType(IO.Path.GetExtension(files.ToLower), Char()))
FilePath = New String(CType(IO.Path.GetDirectoryName(files), Char()))
Filename = New String(CType(IO.Path.GetFileNameWithoutExtension(files), Char()))
ListBox2.Items.Add(FilePath)
Dim maxThreads As String = Nothing
Dim randomc As String
If maxThreads Is Nothing Then
Dim fExt As String = StrConv(FileExt, VbStrConv.ProperCase)
randomc = fExt.Trim(CChar(".")).ToUpper & " "
If randomc = " " Then
randomc = "Unknown"
Else
End If
maxThreads = randomc
End If
Dim sizeInBytes As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(files)
Dim separators() As String = {"*", ","}
Dim filesize As String = CStr(sizeInBytes.Length / 1024)
Dim input As String() = filesize.Split(separators, StringSplitOptions.RemoveEmptyEntries)
filesize = input(0)
Item = New ListViewItem
Item.Text = Filename & FileExt
Item.SubItems.Add(maxThreads)
Item.SubItems.Add(filesize & " KB")
Item.SubItems.Add(FilePath)
Items.Add(Item)
i3 = i2
i2 = i2 + 1
If i2 = 1 Then
Label1.Text = CStr(i2) + " file"
Else
Label1.Text = CStr(i2) + " files"
End If
Label1.Refresh()
Next
Catch ex As Exception
End Try
'go through Listbox1's items
For i = 0 To ListBox1.Items.Count - 1
Try
'search each folder in listbox1 for all subfolders and files
For Each files As String In Directory.EnumerateFiles(CStr(ListBox1.Items(i)), "*.*", SearchOption.AllDirectories)
FileExt = New String(CType(IO.Path.GetExtension(files.ToLower), Char()))
FilePath = New String(CType(IO.Path.GetDirectoryName(files), Char()))
Filename = New String(CType(IO.Path.GetFileNameWithoutExtension(files), Char()))
ListBox2.Items.Add(FilePath)
Dim maxThreads As String = Nothing
Dim randomc As String
If maxThreads Is Nothing Then
Dim fExt As String = StrConv(FileExt, VbStrConv.ProperCase)
randomc = fExt.Trim(CChar(".")).ToUpper & " "
If randomc = " " Then
randomc = "Unknown"
Else
End If
maxThreads = randomc
End If
Dim sizeInBytes As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(files)
Dim separators() As String = {"*", ","}
Dim filesize As String = CStr(sizeInBytes.Length / 1024)
Dim input As String() = filesize.Split(separators, StringSplitOptions.RemoveEmptyEntries)
filesize = input(0)
Item = New ListViewItem
Item.Text = Filename & FileExt
Item.SubItems.Add(maxThreads)
Item.SubItems.Add(filesize & " KB")
Item.SubItems.Add(FilePath)
Items.Add(Item)
i3 = i2
i2 = i2 + 1
If i2 = 1 Then
Label1.Text = CStr(i2) + " file"
Else
Label1.Text = CStr(i2) + " files"
End If
Label1.Refresh()
Next
Catch ex As Exception
End Try
Next
End Sub
End Class