System.UnauthorizedAccessException - доступ к пути запрещен - PullRequest
11 голосов
/ 24 июня 2011

Это немного хитрый, так что терпите меня ...

У меня есть простой маленький метод:

Public Overloads Shared Function DoStuff(ByVal path As String) As Boolean
        If Not IO.File.Exists(ipath) Then Throw New ArgumentException

        Dim result As Boolean
        Using fs As FileStream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
            ' do stuff here, details are not important
            fs.Close()
        End Using

        Return result
    End Function

Я ценю, что метод не показывает, как потокиспользуется, но детали не имеют значения, как я объясню ниже.

Этот метод аккуратно размещен в библиотеке классов; Помощник , на который мы ссылаемся во множестве других проектов.Ясно, что по большей части этот код должен выглядеть нормально, если предположить, что путь допустим, доступен и т. Д.

Теперь проблема.У меня есть библиотека служб WCF, которая ссылается и использует вышеупомянутый метод в сборке Helper .Библиотека служб WCF размещается в службе Windows, которая, в свою очередь, находится на одном из наших серверов.Служба WCF имеет Операцию, которая получает UNC-путь для файла и во время обычного потока вызывает метод, описанный выше в классе Helper.

Путь, который я отправляю, предназначен для файла на общем ресурсе нашегосеть.Строка «Using fs As ...» завершается ошибкой со следующим исключением:

System.UnauthorizedAccessException: Доступ к пути ' мой путь к файлу указан здесь ' запрещен.в System.IO .__ Error.WinIOError (Int32 errorCode, String MaybeFullPath) в System.IO.FileStream.Init (Строковый путь, режим FileMode, доступ FileAccess, права Int32, логические useRights, общий ресурс FileShare, размер буфера Int32, параметры FileOptions, параметры SECURITY_ATTRIBUTES secA, String msgPath, Boolean bFromProxy, Boolean useLongPath) в System.IO.FileStream..ctor (Строковый путь, режим FileMode, доступ FileAccess, общий доступ к FileShare, Int32 bufferSize, параметры FileOptions, String msgPath, Boolean bFromProxy) в System.IO.FileStream..ctor (String path, FileMode mode) в MyHelperAssemblyName.DoStuff (String filePath) в Остальное исключение составляет трассировка стека, указывающая на метод, сборку, службу wcf и т. д."

Теперь список вещей, которые я пытался диагностировать, в том числе глупо очевидные шаги:

  • Скопируйте и вставьте путь, указанный в трассировке стека, в Проводник Windows (оба на моем локальном компьютере).машина и сервер), чтобы убедиться, что файл существует и доступен -> Доступ к файлу
  • Убедитесь, что учетная запись службы Windows имеет достаточные права на чтение файла -> Действующие разрешения перечисляют учетную запись службы как имеющую полный доступ
  • Измените учетную запись службы Windows, чтобы использовать мою личную учетную запись администратора (временная мера), и, очевидно, перезапустите службу, чтобы изменения вступили в силу -> Сбой той же строки кода
  • Скопируйте каталог, содержащий файл, на мой локальный компьютер и запустите службу на моем локальном компьютере (мы хотели убедиться, что причина не в NAS, на котором размещен файл) -> Сбой той же строки кода
  • Создайте быстрое консольное приложение, скопируйте, вставьте код из метода вспомогательной сборки в приложение, введите тот же путь к файлу, запустите его локально, а затем на сервере (я имею в виду на сервере.удаленное подключение к серверу с использованием той же учетной записи администратора, которую я упоминал ранее, и запуск его) -> Приложение имеетнет проблем с запуском кода
  • Создайте консольное приложение и используйте массовый стандартный способ размещения библиотеки служб WCF в консольном приложении.Запустите приложение локально, а затем, используя WcfStorm для локального адреса, который я указал в качестве базового адреса для приложения консоли, вызовите тот же метод с тем же путем, по которому происходит сбой обычной службы -> Результаты WcfStorm подтверждают, что с кодом проблем не было
  • Дважды проверьте код библиотеки служб WCF, чтобы убедиться в отсутствии какой-либо особой условной логики, которая могла бы повлиять на мои тесты -> Вспомогательный метод вызывается почти сразу после запуска реализации операции службы (сразу после проверки аргумента ). Операция не может возвращать согласованные результаты без выполнения вспомогательного метода, поэтому, когда я ранее получал согласованные результаты и предполагал, что был запущен «странный» код доступа к файлу, он выполнялся, infact был запущен
  • Повторно развернул Службу с чистыми перестройками узла службы Windows, библиотеки служб WCF и вспомогательной сборки (хотел убедиться, что код на моем экране действительно влиял на код, работавший на сервере) -> Без изменений
  • РЕДАКТИРОВАТЬ 2011-06-24 16: 32GMT - Используя консольное приложение, которое я создал ранее, для размещения службы WCF, соответствующим образом измените baseAddress и разверните его на сервере. Запустите приложение, используя ту же учетную запись администратора, как указано выше. Протестируйте новое приложение по новому базовому адресу с помощью WcfStorm. -> Код работает, как ожидалось, и дает хорошие результаты (я полагаю, что на данном этапе сужается до того, что он является ошибкой службы Windows?)
  • EDIT 2011-06-27 10: 21GMT - Создана простая служба Windows, ссылающаяся на класс помощника. Устанавливается на сервере, учетная запись службы устанавливается так же, как Live Server. -> Новая служба смогла запустить код и получить доступ к файлу
  • РЕДАКТИРОВАТЬ 2011-06-27 10: 23GMT - Раздраженный тем, что служба сработала, я открыл WcfStorm, который оставил работать на выходных. С пятницы были показаны результаты, показывающие, что в прямом эфире произошел сбой. Я не отвечаю на тот же запрос -> Это сработало ... Сейчас я на самом деле более раздражен, потому что у меня нет реальных средств для отслеживания проблемы

    Итак, сервис пока работает правильно. У кого-нибудь есть идеи, что может вызвать такой прерывистый сбой? Сотрудники заверяют меня, что за выходные ничего не изменилось (по крайней мере, вручную). Расстроенный ...

Ответы [ 4 ]

4 голосов
/ 01 июля 2011

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

1 голос
/ 03 июля 2011

У меня есть несколько догадок.

Вы пытались установить «FileAccess.Read» и / или «FileShare.Read» на «ReadWrite»?

Также возможно ли это предупреждениеможет быть фактором?С http://msdn.microsoft.com/en-us/library/5h0z48dh.aspx:

Внимание

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

1 голос
/ 02 июля 2011

Использует ли ваша служба WCF олицетворение?

Это объясняет, почему новая служба Windows может выполнять действие, а служба WCF - нет. Новый сервис аутентифицируется непосредственно против NAS. Если в старой службе WCF выдавал себя за вызывающего, клиентский компьютер аутентифицирует пользователя, их токен передается службе WCF, которая, в свою очередь, передает маркер безопасности на NAS, и вы нажимаете double hop * 1004. * проблема.

Вы можете вернуть активный контекст безопасности к учетной записи службы, например this :

using (WindowsIdentity.Impersontate(IntPtr.Zero))
{
    DoStuff();
}

Конечно, это не объясняет, почему это могло работать с перебоями. Но это объясняет работу службы WCF при локальном ее вызове на компьютере, на котором она размещена, но не с удаленного клиентского компьютера.

1 голос
/ 27 июня 2011

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

...