Служба Windows самопроизвольно теряет доступ к временной папке

У меня есть служебное приложение Windows, которое в рамках обработки сообщений MSMQ записывает в каталог TEMP учетной записи, под которой оно работает. Итак, если бы служба работала под MYDOMAIN \ foo, каталог TEMP был бы C:\Users\foo\AppData\Local\Temp\. Соответствующий код:

Guid key = Guid.NewGuid();
string tempPdf = Path.Combine(Path.GetTempPath(), string.Format("{0:D}.pdf", key));
byte[] output = GetSomeData();  // Gets in-memory PDF data, in this case the output from an SSRS report
File.WriteAllBytes(tempPdf, output);

Обычно это работает без проблем. С кажущимися случайными интервалами (иногда пару раз в один день, иногда через пару дней) процесс начинает давать сбой при вызове File.WriteAllBytes. Исключение составляют:

System.UnauthorizedAccessException: доступ к пути C: \ Users \ foo \ AppData \ Local \ Temp \ a2b5b6b0-7c25-42a4-a475-771b8f4c525e.pdf запрещен.

Перезапуск сервиса все исправляет, по крайней мере, временно.

Место на диске в порядке. Разрешения кажутся нормальными для папки TEMP. В журнале событий нет ничего интересного, кроме указанной выше ошибки приложения. Это работает на Windows Server 2012 R2.

Трассировка стека:

System.UnauthorizedAccessException: Access to the path 'C:\Users\foo\AppData\Local\Temp\eb29dd49-d3c5-486f-8a9b-fface4857448.pdf' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.File.InternalWriteAllBytes(String path, Byte[] bytes, Boolean checkHost)

Есть идеи, что может быть причиной этого, или советы, чтобы отследить, где может быть проблема?


person Dave Mateer    schedule 04.08.2017    source источник
comment
может что-то очищать временную папку? файл заблокирован?   -  person Daniel A. White    schedule 04.08.2017
comment
Есть ли что-то еще в сообщении об исключении, чем это? Я думал, что UnauthorizedAccessException укажет причину, почему отказано в доступе.   -  person Steven Rands    schedule 04.08.2017
comment
@ DanielA.White: в приведенном выше коде файл создается впервые со случайным идентификатором GUID, поэтому он не существует до того, как WriteAllBytes завершился ошибкой. Так что блокировка - это не вариант. Что касается очистки временной папки, я так не думаю, потому что там все еще есть другие файлы, и я не вижу никаких задач, которые пытались бы это сделать.   -  person Dave Mateer    schedule 04.08.2017
comment
@StevenRands: Нет, это объем сообщения. Трассировка стека есть, но это все вызовы в пространстве имен System.IO, происходящие из вызова WriteAllBytes. Я включу стек выше.   -  person Dave Mateer    schedule 04.08.2017
comment
@DaveMateer может ли это получить антивирус?   -  person Daniel A. White    schedule 04.08.2017
comment
Возможно, попробуйте создать пустой временный файл с помощью Path.GetTempFileName(), записать в него с помощью WriteAllBytes(), а затем переименовать файл в самом конце: посмотрите, по-прежнему ли вы получаете исключение таким образом.   -  person Steven Rands    schedule 04.08.2017
comment
@ DanielA.White Хорошее предложение: AV может обнаружить файл PDF и предполагает, что его нужно сканировать. Если программа AV открывает файл, это может вызвать исключение.   -  person Steven Rands    schedule 04.08.2017
comment
Мне нужно будет задействовать ресурс безопасности, чтобы исключить этот каталог. Это, вероятно, займет некоторое время - я обновлю вопрос, как только определю, имеет ли это значение. Спасибо за идею.   -  person Dave Mateer    schedule 04.08.2017


Ответы (1)


Это закончилось проблемой олицетворения. Это был совершенно отдельный процесс, работавший под той же службой Windows, который инкапсулировал некоторый код в вызове олицетворения. Этот код не был реализован чисто, так что необработанное исключение не смогло прервать олицетворение, так что другие (несвязанные) процессы все еще работали под олицетворенной учетной записью, которая, очевидно, не имела доступа к временной папке пользователя службы.

Я смог увидеть это после запуска Process Monitor и просмотра подробностей события ACCESS DENIED.

person Dave Mateer    schedule 10.08.2017