ledtech3 Ответов: 3

Исключение Несанкционированного Доступа


Каждый пример приложения для поиска файлов, который я нахожу при попытке рекурсии через файловую систему, сталкивается с UnauthorizedAccessException в 1 папке или другой.
Я некоторое время искал в интернете и не нашел подходящего решения, так как большинство примеров безопасности предназначены для консольных приложений и плохо подходят для приложений windows form или просто не работают.

Я пробую 1 из образцов VS2008, который называется filesystemsample и использует фоновый рабочий.

Образец был скачан:
загрузка\против 2008 РТМ vbsamples\ВБ 2008 РТМ примеры\образцы\язык\файловая система FileSystemSample.СЛН

В этом образце нет импорта ни для чего.

То , что я хочу сделать, это иметь возможность искать строку в файле и возвращать список файлов, что примерное приложение делает до тех пор, пока не попадет в исключение.

До сих пор я использовал класс wmi для поиска файлов, но не содержимого, чтобы обойти проблему исключения, но мне нужно что-то для этой конкретной цели.

Любая помощь будет оценена по достоинству

Sander Rossel

Вы работаете в качестве администратора? Первое, что приходит на ум, когда речь идет о безопасности и привилегиях доступа :)

ledtech3

Да ,но все, что я могу сделать, это обнаружить ошибку.не знаете, как сделать файл разрешения доступа.

Simon_Whale

можете ли вы опубликовать образец кода, где происходит ошибка?

3 Ответов

Рейтинг:
2

ledtech3

У него есть блок try catch,
Вот фоновый рабочий

Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
       Try
           Dim files As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
           ' Look in each file matching the provided wildcards
           If (recurse) Then
               files = My.Computer.FileSystem.FindInFiles(directory, searchText, True, FileIO.SearchOption.SearchAllSubDirectories, wildCards)
           Else
               files = My.Computer.FileSystem.FindInFiles(directory, searchText, True, FileIO.SearchOption.SearchTopLevelOnly, wildCards)
           End If
           For Each foundFile As String In files
               Me.BackgroundWorker1.ReportProgress(0, foundFile)
           Next
       Catch ex As Exception
           MsgBox(ex.Message & vbCrLf & ex.Source, MsgBoxStyle.Information, "Exception Message")
       End Try
   End Sub


ledtech3

Я работаю над этим уже некоторое время и до сих пор не нашел способа вставить процедуру проверки разрешения файлов в микс, чтобы поймать ошибку и двигаться дальше, чтобы я мог продолжать проверку в рекурсивном поиске.
С момента моего первого поста я переместил код в свой собственный проект, а затем должен был декларировать несколько частных vaiables.
1 странная вещь действительно произошла после добавления импорта для system и system. security, а затем подписала сборку ключом строгого имени, казалось, что она справляется с ошибкой более изящно.Он просто прекратит поиск, как будто ничего не нашел, а не выдаст ошибку и не отобразит окно сообщения(большую часть времени).
Иди Разберись.
Но тем не менее он прекратил поиски.

Если recursive = FALSE, то он просто проверит (свободные) файлы в папке и вернет список файлов,найденных с заданной строкой поиска, если таковые имеются.

Если recursive = TRUE, то он получит ошибку Access Denied для папки, в которой начинается поиск, и завершит поиск. В этом случае папка и путь = C:\ProgramData (64-битная система Vista)

Мне нужно лучше понять, как работает безопасность и фоновый работник.
В большинстве примеров используются консольные приложения, которые не имеют дела с объектами windows forms.

Есть еще идеи ??

Спасибо, что уделили мне время.

ledtech3

После дальнейшего расследования выясняется, что ошибка несанкционированного доступа проистекает из точек повторного анализа, в которые она попадает, а не из обычной проблемы безопасности.
Я скачал и обновил код, указанный здесь . http://www.codeproject.com/KB/vista/ReparsePointID.aspx
И в настоящее время я пытаюсь понять, могу ли я использовать там dll reparse point.
Она написана на языке Си, а я парень из vb, так что это может занять немного времени, чтобы понять.

Mitchster

В своих решениях я тоже дошел до этого. Вот как я справляюсь с этим: как только вы можете определить точку повторного анализа (которая должна быть перед запуском кода "найти"), я просто пропускаю эту вещь. В моем случае все точки повторного анализа находятся на диске, так что они будут "поражены", когда я доберусь до их фактического местоположения. Удачи.

Dave Kreskowiak

Ты ведь знаешь, что этой нити больше пяти лет, верно? Я думаю, что разговор в значительной степени мертв.

Mitchster

Но проблема не в этом. Сделайте мне одолжение и дайте мне список всех файлов на вашем компьютере, измененных за последнюю неделю, или с буквами "кошка" в имени файла. Не список из десяти тысяч файлов и папок, которые их содержат, а именно этот отчетливый список... :)

Dave Kreskowiak

И только какая от этого будет польза?

Да, я могу сделать это довольно легко. Нет, я не собираюсь "делать тебе одолжение", делая это. Это проблема, которая была решена бесчисленное количество раз во всем интернете. Вам не нужно воскрешать пятилетние нити, чтобы решить ее снова.

ОП даже нашел решение, которое он мог бы приспособить сам. На самом деле вам не нужно было добавлять в дискуссию "я просто пропустил точки повторного анализа".


Mitchster

Религиозный спор; потому что я так говорю.
Таким образом, вы можете искать любые файлы на любом из ваших дисков по явным критериям. И вы можете вытащить все защищенные файлы Windows, которые соответствуют этим критериям... и без каких-либо проблем с несанкционированным доступом. Я исправляюсь. Ты хороший. Я отправлял сообщение кому-то, кто пытался попасть "туда". Пропуск точек повторного анализа в высшей степени применим; мы ищем диски.

ledtech3

снова смотрю на код.
Проблема заключается в том, как microsoft обрабатывает ошибку (или не обрабатывает) в функции
"FindInFiles" (dPath, searchtext, True, FileIO.Searchoption указывает, нужно.SearchAllSubDirectories, подстановочные знаки)
Он начинается с поиска всех файлов и папок в выбранном вами начальном каталоге.
Если одна из папок, которую он находит, является точкой повторного разбора или перенаправлением и / или не разрешает доступ, то он выдает ошибку и выходит из функции. Так что если вы не будете искать только папки или файлы сами по себе то эта функция может не принести большой пользы

Фактическая ошибка, о которую он спотыкается, такова.
Система.UnauthorizedAccessException

Поэтому я должен создать новую функцию, которая правильно обрабатывает ошибку.
Он просто выходит из поиска, как есть, без каких-либо результатов.

ledtech3

Нашел класс и функцию здесь http://www.vbforums.com/showthread.php?t=341919
Это работает вокруг проблемы, но результат-это еще не то, что я хочу.
Он все еще нуждается в некоторой настройке или переписывании с использованием той же идеи.

Рейтинг:
19

pdoxtader

Я думаю, что это то, что вы хотели:

Используя этот код, я смог получить список всех файлов на моем диске c:, к которым у меня есть доступ, исключая те, к которым у меня его нет. Исключение не было сделано (во всяком случае, оно не было поймано). Когда у вас есть список, достаточно просто перечислить их, чтобы найти нужную строку.

Private Function GetFilesList(ByVal theFolder As String, Optional ByVal recurseSubdirectories As Boolean = True) As List(Of String)
        Dim filesList As New List(Of String)
        Dim foldersList As New List(Of String)
        Dim tmp As New List(Of String)

        Dim dir As New IO.DirectoryInfo(theFolder)
        If Not dir.Exists Then
            ' Our folder doesn't exist. Handle it here.
            Return Nothing
        End If

        ' Get the files in this folder...
        Try
            filesList.AddRange(Directory.GetFiles(theFolder))
            foldersList.AddRange(Directory.GetDirectories(theFolder))

        Catch ex As Exception
            ' The folder exists, but we don't have access to it.
            Return Nothing
        End Try

        ' Do they only want the files in THIS folder?
        If Not recurseSubdirectories Then
            Return filesList
        Else
            'If there are directories in this folder process them
            For Each folder As String In foldersList
                tmp = GetFilesList(folder)
                If tmp IsNot Nothing Then filesList.AddRange(tmp)
            Next

            Return filesList
        End If

    End Function


ledtech3

Я начал писать с идеей списка подпапок, ловящих те, которым отказано в доступе.
Но моя нынешняя версия была не очень хороша.
Я попробую твой пример и дам тебе знать.
Спасибо за пост

ledtech3

Если я использую его как есть с recurse = True, то получаю ошибку условия взаимоблокировки, если он не работает внутри фонового рабочего.

Кое-что интересное я обнаружил, тестируя свой код с помощью
Системы.ИО.Каталог.GetDirectories(StartDir)
Разве что он никогда не бросал UnauthorizedAccessException
Шагая через код, чтобы получить список папок.

pdoxtader

Ну и как долго вы ждали? Если вы ищете весь свой жесткий диск, это может занять больше времени, чем вам хотелось бы. Естественным решением этой проблемы является немедленное начало поиска строк... например, вместо того, чтобы:


filesList.AddRange(Directory.GetFiles(theFolder))


создайте новый список, содержащий только файлы в этой папке, и передайте их вашей функции поиска строк.

Кроме того, попробуйте запустить это снова, и когда вам покажется, что Вы зашли в тупик, подождите некоторое время. Давайте посмотрим, не займет ли это какое-то время, чтобы просмотреть ваши папки.

ledtech3

Я не использовал никаких потоковых или фоновых рабочих, поэтому через 60 секунд он сказал, что он не отвечает или находится в состоянии взаимоблокировки. Я запускал это через отладчик. и, похоже, он ничего не делал, глядя на него через Process Explorer. Сначала я подумал, что это просто потому, что я пытался вернуть поиск файлов в начальной папке и вернуть найденные файлы в тот же список. но после комментария к первой части эффект остался тот же. Но если вы просто получите список подпапок, это будет сделано за пару секунд. Моя тестовая папка - это C: \ Users \ David \ AppData, потому что я знаю, что есть несколько папок, которые вызывают исключение.

ledtech3

Извините, выпил немного кофе, я переделал пример приложения, и ваш код прекрасно работает сам по себе. Проблема была в моей модифицированной версии. Именно тогда,когда я пытаюсь также вернуть, какие папки выбрасывают исключение, когда я сталкиваюсь с проблемой, этот код запутывается, пытаясь сделать несколько разных вещей.
То, что я пытаюсь сделать, это получить список файлов, в которых находится строка, а также получить список, который вызывает исключение, чтобы я мог войти вручную и проверить, что то, что я ищу, не скрыто там.

ledtech3

Ой, я споткнулся на "Optional ByVal recurseSubdirectories As Boolean = True", я ввел false и забыл его изменить.

Что это такое кидать
ContextSwitchDeadlock был обнаружен
Сообщение: CLR не смогла перейти из COM-контекста 0x1c751600 в COM-контекст 0x1c751850 в течение 60 секунд. Поток, которому принадлежит целевой контекст / квартира, скорее всего, либо выполняет ожидание без перекачки, либо обрабатывает очень длительную операцию без перекачки сообщений Windows. Эта ситуация обычно оказывает негативное влияние на производительность и может даже привести к тому, что приложение перестает отвечать или использование памяти постоянно накапливается с течением времени. Чтобы избежать этой проблемы, все потоки однопоточного подразделения (STA) должны использовать примитивы ожидания перекачки (такие как CoWaitForMultipleHandles) и регулярно перекачивать сообщения во время длительных операций.
Но если вы нажмете кнопку Продолжить и оставите его в покое, он действительно закончит и вернет список.

pdoxtader

Попробуйте запустить его в фоновом потоке. Я запустил его в потоке пользовательского интерфейса, когда тестировал, но у меня довольно быстрая машина...

ledtech3

У меня тоже есть быстрая машина, просто выделите файлы, чтобы пройти через папку .C:\Users\David\AppData\Local) составляет 19,5 ГБ. Мне придется запустить его в фоновом режиме, когда в папке "пуск" будет выделено множество вложенных папок и файлов, что должно решить проблему и позволить мне минимизировать пользовательский интерфейс во время поиска. Еще раз спасибо за ваш пост.

ledtech3

Хотя ваш код не привел меня полностью туда, где я хотел быть, он ответил на первоначальный вопрос об обработке исключения несанкционированного доступа.
Поэтому я отметил ваш ответ как ответ и дал вам 5.
Еще раз спасибо за ваше время и публикацию кода.

pdoxtader

НП. рад, что смог помочь.

Рейтинг:
0

Dave Kreskowiak

На диске есть папки и файлы, доступ к которым не разрешен ни одной учетной записи. Ваш код должен быть написан, чтобы справиться с этой ситуацией, например, обернуть вызовы GetFiles и GetDirectories в блок Try/Catch. На самом деле это не так уж и сложно.


Espen Harlinn

Правильно :)

fjdiewornncalwe

Совершенно правильный. +5