2009-10-15 5 views
1

Я понимаю, что .NET 4.0 находится в бета-версии, но я надеюсь, что у кого-то есть разрешение на это. Я пытаюсь создать в памяти, в файл из библиотеки DLL:MemoryMappedFile.CreateFromFile всегда выбрасывает UnauthorizedAccessException

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 documentation состояния:

Операционная система отклонил указанный доступ к файлу; например, для доступа задано значение Write или ReadWrite, но файл или каталог доступны только для чтения.

Я отслеживаю свое приложение с помощью Sysinternals Process Monitor, который показывает, что файл действительно успешно открывается. Я также попробовал сопоставление памяти с другими файлами, отличными от DLL, но с тем же результатом.

+0

Это похоже на дубликат: http://stackoverflow.com/questions/1220913/unauthorizedaccessexception-on-memorymappedfile-in-c-4 – bobbymcr

ответ

8

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

  • Я только указанные MemoryMappedFileAccess.Read при создании MemoryMappedFile. Вы открыли его для чтения, поэтому можете читать только. Я не пробовал исправлять его, чтобы разрешить выполнение, изменив способ открытия FileStream.
  • Я сделал звонок CreateViewStream явно использовать MemoryMappedFileAccess.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 
      } 
     } 
    } 
} 
+0

Этот код работает и для меня. Однако то, что я пытаюсь сделать, это получить DLL, загруженную в память, как будто она должна была быть выполнена, поэтому я могу избежать выполнения всего отображения раздела PE при чтении таблицы экспорта DLL. Для этого мне нужно сопоставить файл с доступом ReadExecute. Но, похоже, не существует соответствующего файла FileAccess.ReadExecute или даже флаг FileAccess.Execute для FileStream.Open(). –

+0

Справа. Я посмотрю, что я могу сделать, но я думаю, что есть некоторое расстояние между «Я не могу использовать его для этой цели» и «это совершенно непригодно» :) –

+0

Действительно. Возможно, я был немного суровым в этом отношении. Фактически, в то время я не понимал, что существует разница между тем, как файл открывается для доступа для чтения и для доступа ReadExecute. Я думал, что это просто вопрос о том, как файл был обработан ** после ** открытия. Спасибо за помощь, кстати! –

6

У меня было такое же поведение при вызове CreateViewAccessor (...) метод.

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

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

+0

У меня была такая же проблема. –

+0

В .NET 4.5.2 это вводящее в заблуждение исключение все еще бросается. – fero

Смежные вопросы