MemoryMappedFile.CreateFromFile всегда выдает исключение UnauthorizedAccessException
-
21-09-2019 - |
Вопрос
Я понимаю, что .NET 4.0 находится в стадии бета-тестирования, но я надеюсь, что у кого-нибудь есть решение для этого.Я пытаюсь создать файл с отображением в памяти из библиотеки DLL:
FileStream file = File.OpenRead("C:\mydll.dll");
using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile(file,
"PEIMAGE", 1024 * 1024, MemoryMappedFileAccess.ReadExecute))
{
using (MemoryMappedViewStream viewStream = mappedFile.CreateViewStream())
{
// read from the view stream
}
}
К сожалению, что бы я ни делал, я всегда получаю UnauthorizedAccessException
, для которого Документация MSDN состояния:
Операционная система отказала в указанном доступе к файлу;например, для access задано значение Write или ReadWrite, но файл или каталог доступны только для чтения.
Я отслеживал свое приложение с помощью Sysinternals Process Monitor, который показывает, что файл действительно успешно открывается.Я также пробовал сопоставлять память с другими файлами, отличными от DLL, но с тем же результатом.
Решение
Что ж, у меня есть пример, основанный на приведенном выше, который выполняется без исключений.Я внес два важных изменения:
- Я только уточняю
MemoryMappedFileAccess.Read
при созданииMemoryMappedFile
.Вы открыли его для чтения, так что вы можете только читать.Я также не пытался исправить это, чтобы разрешить выполнение, изменив способFileStream
открывается. - Я сделал то, что
CreateViewStream
вызовите явно useMemoryMappedFileAccess.Read
также.Я не уверен, почему он сам по себе не использует существующие права доступа, но так и есть.
Полная программа:
using System.IO;
using System.IO.MemoryMappedFiles;
class Test
{
static void Main()
{
FileStream file = File.OpenRead("Test.cs");
using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile
(file, "PEIMAGE", file.Length, MemoryMappedFileAccess.Read, null, 0, false))
{
using (var viewStream = mappedFile.CreateViewStream
(0, file.Length, MemoryMappedFileAccess.Read))
{
// read from the view stream
}
}
}
}
Другие советы
У меня было такое же поведение при вызове метода CreateViewAccessor(...).
Оказывается, ошибка выдавалась только тогда, когда параметр size превышал длину файла (это не то же самое поведение, к которому мы привыкли с потоками, где size - максимальное значение, вместо этого, похоже, параметр принимается как литерал, и результатом является попытка чтения дальше конца файла).
Я исправил свою проблему, проверив, что размер не превышает размер открытого файла.