UnauthorizedAccessException 时如何跳过目录或文件

How to skip directory or file when UnauthorizedAccessException

我正在编写一个应用程序,用于从特定路径(包括系统路径,例如 Windows 目录、Program Files、Application Data 等)检查计算机是否有病毒

用户将单击按钮 "Start scan",将开始检查系统文件(包括 Windows/ProgramFiles 目录)是否有病毒,将文件与名为 "viruslist.txt" 的文本文件的 MD5 哈希进行比较

但是,我遇到了一些 UnauthorizedAccessException 错误问题。当检测到无法访问的文件时,应用程序将停止。

我希望应用程序跳过被拒绝的文件并转到特定路径中的下一个文件。

我的代码如下: 后台工作代码:

    Try
        For Each file As String In IO.Directory.EnumerateFiles(FolderBrowserDialog3.SelectedPath, IO.SearchOption.AllDirectories).Union(IO.Directory.EnumerateFiles(FolderBrowserDialog4.SelectedPath, "*", IO.SearchOption.AllDirectories))
            Try
                Dim scanbox As New TextBox
                Dim read As String = My.Computer.FileSystem.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory & "viruslist.txt")
                scanbox.Text = read.ToString
                Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
                Dim f As FileStream = New FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
                f = New FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
                md5.ComputeHash(f)
                Dim hash As Byte() = md5.Hash
                Dim buff As StringBuilder = New StringBuilder
                Dim hashByte As Byte
                For Each hashByte In hash
                    buff.Append(String.Format("{0:X2}", hashByte))
                Next

                If scanbox.Text.Contains(buff.ToString) Then

                    AddListItem2(ListBox2, "" & file & "")
                End If
            Catch ex As Exception
            End Try
            '   SetLabelText_ThreadSafe(Me.Label1, "" & file & "")
            If (BackgroundWorker1.CancellationPending = True) Then

                e.Cancel = True
                Exit For
            End If
            SetLabelText_ThreadSafe(Me.Labelscannedfiles, file & "")
            int = int + 1
            SetLabelText_ThreadSafe(Me.Label2, int & " Out Of " & filecount & "")
            Dim pct As Integer = (int / filecount * 100)
            BackgroundWorker1.ReportProgress(pct)
        Next file
  Catch ex as unauthorizedaccessexception

另外,按钮代码(开始扫描):

 FolderBrowserDialog3.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.Windows)

        Try
            For Each strDir As String In
                System.IO.Directory.GetDirectories(FolderBrowserDialog3.SelectedPath)

                For Each strFile As String In System.IO.Directory.GetFiles(strDir)



                Next
            Next
        Catch ex As Exception

Listbox2- 用于显示检测到的感染对象。 我尝试了以下方法:

到目前为止没有任何效果!

更新 感谢 JQSOFT 为我的问题提供解决方案。下面的解决方案肯定会帮助很多遇到同样问题的人。这个问题已经解决了。

这里有几点。

'Set this to True in the Cancel button...
Private cancel As Boolean

Sub New()
    InitializeComponent()
    '...

    BackgroundWorker1.WorkerReportsProgress = True
    BackgroundWorker1.WorkerSupportsCancellation = True
End Sub

使用此迭代器函数获取授权的文件和文件夹:

Private Iterator Function IterateFolders(startDir As String, 
                                         includeFiles As Boolean, 
                                         includeSubDir As Boolean) As IEnumerable(Of String)
    Try
        For Each dirName In Directory.EnumerateDirectories(startDir)
            Yield dirName

            Try
                If includeFiles Then
                    For Each fileName In Directory.EnumerateFiles(startDir)
                        Yield fileName
                    Next
                End If

                If includeSubDir Then
                    For Each subDir In IterateFolders(dirName, includeFiles, includeSubDir)
                        Yield subDir
                    Next
                End If
            Catch ex As UnauthorizedAccessException
            Catch ex As Exception
            End Try
        Next
    Catch ex As UnauthorizedAccessException
    Catch ex As Exception
    End Try
End Function

开始扫描按钮

Private Sub Scan_Click(sender As Object, e As EventArgs) Handles Scan.Click
    If BackgroundWorker1.IsBusy Then Return
    Using fbd As New FolderBrowserDialog
        If fbd.ShowDialog = DialogResult.OK Then
            cancel = False
            '...
            BackgroundWorker1.RunWorkerAsync(fbd.SelectedPath)
        End If
    End Using
End Sub

BackgroundWorker 事件:

Private Sub BackgroundWorker1_DoWork(sender As Object,
                                     e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim dir = e.Argument.ToString

    For Each file In IterateFolders(dir, True, True).
            Where(Function(f) IO.File.Exists(f)) '<- To get the files only.
        If cancel Then
            e.Cancel = True
            Return
        End If

        Try

            Dim b As Boolean = False

            Using md5 As New MD5CryptoServiceProvider,
                f As FileStream = New FileStream(file, 
                                             FileMode.Open, 
                                             FileAccess.Read, 
                                             FileShare.Read, 8192)

                md5.ComputeHash(f)

                Dim hash As Byte() = md5.Hash
                Dim buff As New StringBuilder
                Dim hashByte As Byte

                For Each hashByte In hash
                    buff.Append(String.Format("{0:X2}", hashByte))
                Next

                b = IO.File.ReadLines("...FullPathOf\viruslist.txt").
                Any(Function(x) x = buff.ToString)
            End Using

            'The main thread...
            Invoke(New Action(Sub()
                                    If b Then ListBox2.Items.Add(file)
                                    Labelscannedfiles.Text = ....
                                    Label2.Text = $"{int} Out of {filecount}"
                              End Sub))

            'Code to update the progress here...
        Catch ex As IOException
        Catch ex As Exception
        End Try
    Next
End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As Object,
                                              e As ProgressChangedEventArgs) _
                                              Handles BackgroundWorker1.ProgressChanged
    'Update the progress...
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object,
                                                 e As RunWorkerCompletedEventArgs) _
                                                 Handles BackgroundWorker1.RunWorkerCompleted
    If e.Error IsNot Nothing Then
        'An error occurred
    ElseIf e.Cancelled Then
        'Operation canceled...
    Else
        'On success ....
    End If
End Sub