MemoryMappedFile.CreateFromFile sempre lança UNAuthorizedAccessException
-
21-09-2019 - |
Pergunta
Sei que o .NET 4.0 está na versão beta, mas espero que alguém tenha uma resolução para isso. Estou tentando criar um arquivo mapeado de memória a partir de uma 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
}
}
Infelizmente, não importa o que eu faça, sempre recebo um UnauthorizedAccessException
, para o qual o Documentação do MSDN estados:
O sistema operacional negou o acesso especificado ao arquivo; Por exemplo, o acesso está definido para escrever ou readwrite, mas o arquivo ou diretório é somente leitura.
Monitorei meu aplicativo com o SysInternalths Process Monitor, que mostra que o arquivo está realmente sendo aberto com sucesso. Também tentei o mapeamento de memória de outros arquivos não-DLL, mas com o mesmo resultado.
Solução
Bem, eu tenho um exemplo baseado no acima que funciona sem exceções. Eu fiz duas mudanças importantes:
- Estou especificado apenas
MemoryMappedFileAccess.Read
Ao criar oMemoryMappedFile
. Você o abriu para leitura, para que você possa ler apenas. Eu não tentei consertá -lo para permitir a execução também mudando como oFileStream
está aberto. - Eu fiz o
CreateViewStream
Ligue para usar explicitamenteMemoryMappedFileAccess.Read
também. Não sei por que isso não usa os direitos de acesso existente por si só, mas lá vamos nós.
Programa completo:
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
}
}
}
}
Outras dicas
Eu tive o mesmo comportamento ao chamar o método CreateViewAccessor (...).
Acontece que o erro só foi lançado quando o parâmetro de tamanho excedeu o comprimento do arquivo (não é o mesmo comportamento que estamos acostumados com fluxos onde o tamanho é um valor máximo, em vez disso, parece tomar o parâmetro como literal e O resultado é uma tentativa de ler além do final do arquivo).
Corrigi meu problema verificando se o tamanho não excede o tamanho do arquivo aberto.