MemoryMappedFile.CreateFromFile siempre lanza UnauthorizedAccessException
-
21-09-2019 - |
Pregunta
Me doy cuenta de .NET 4.0 está en fase beta, pero estoy esperando que alguien tiene una resolución de este. Estoy intentando crear un archivo de mapeado de memoria desde un archivo 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
}
}
Por desgracia, no importa lo que haga, siempre obtengo un UnauthorizedAccessException
, para el que el documentación de MSDN afirma:
El sistema operativo negó el acceso especificado en el fichero; por ejemplo, acceso está configurado para escribir o ReadWrite, pero el archivo o directorio es de sólo lectura.
He monitoreado mi solicitud con el monitor de procesos de Sysinternals, que muestra que el archivo de hecho se está abriendo con éxito. También he tratado de asignación de memoria otros archivos no DLL, pero con el mismo resultado.
Solución
Bueno, tengo un ejemplo basado en lo anterior, que se ejecuta sin excepciones. He hecho dos cambios importantes:
- Sólo estoy especifica
MemoryMappedFileAccess.Read
al crear elMemoryMappedFile
. Has abierto para lectura, por lo que sólo puede leer. No he probado su fijación a permitir ejecutar, así cambiando la forma en que se abre laFileStream
. - He hecho la llamada
CreateViewStream
utilizar explícitamenteMemoryMappedFileAccess.Read
también. No estoy seguro de por qué no utiliza los derechos de acceso existentes por sí mismo, pero hay que ir.
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
}
}
}
}
Otros consejos
Yo tenía el mismo comportamiento cuando se llama al método CreateViewAccessor (...).
Resulta que el error sólo se produce cuando el parámetro de tamaño excede la longitud del archivo (que no es el mismo comportamiento que estamos acostumbrados con las corrientes donde el tamaño es un valor máximo, en cambio, parece tener el parámetro como un literal y el resultado es un intento de leer más allá del final del archivo).
Me fijo mi problema mediante la comprobación de que el tamaño no supere el tamaño del archivo abierto.