Открытие сопоставленного с памятью файла вызывает FileNotFoundException при развертывании в IIS
следующий пример кода этой веб-сайт, я создал консольное приложение windows, которое создает сопоставленный файл памяти:
using (var file = MemoryMappedFile.CreateNew("myFile", 24))
{
var bytes = new byte[24];
for (var i = 0; i < bytes.Length; i++)
bytes[i] = (byte)(65 + i);
using (var writer = file.CreateViewAccessor(0, bytes.Length))
{
writer.WriteArray<byte>(0, bytes, 0, bytes.Length);
}
Console.WriteLine("Run memory mapped file reader before exit");
Console.WriteLine("Press any key to exit ...");
Console.ReadLine();
}
в новом asp.net веб-приложение я читаю MMF, используя код:
protected void Page_Load(object sender, EventArgs e)
{
string sOutput = "";
using (var file = MemoryMappedFile.OpenExisting("myFile"))
{
using (var reader = file.CreateViewAccessor(0, 24))
{
var bytes = new byte[24];
reader.ReadArray<byte>(0, bytes, 0, bytes.Length);
for (var i = 0; i < bytes.Length; i++)
sOutput += (char)bytes[i] + " ";
}
}
Response.Write(sOutput);
}
в IIS Express разработки файл считывается как ожидалось, и на странице отображаются данные из файла сопоставленной памяти.
однако при развертывании в IIS я получаю исключение System.IO.FileNotFoundException
в местоположениеMemoryMappedFile.OpenExisting("myFile")
Я попытался изменить идентификатор пула приложений на тот же, что и при запуске консольного приложения MMF, но это не сработало.
3 ответов
добавьте префикс" Global\\ " к имени карты. Только так это сработало для меня. Когда мы пытаемся получить доступ к общей памяти, созданной в первом процессе, он запускается в другом контексте безопасности, и объекты общей памяти не видны, если они не созданы в глобальном пространстве имен.
Это код, который работал для меня. Я использовал CreateOrOpen в приложении WinForm, и я использовал OpenExisting в процессе IIS:
mSec = new MemoryMappedFileSecurity();
mSec.AddAccessRule(new AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MemoryMappedFileRights.FullControl, AccessControlType.Allow));
mmf = MemoryMappedFile.CreateOrOpen("Global\\MmfName", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, mSec, HandleInheritability.Inheritable);
mmf = MemoryMappedFile.OpenExisting("Global\\MmfName");
Если вы пытаетесь достичь Межпроцессной связи (IPC), вы можете использовать WCF с привязкой именованного канала. Вы получаете много простоты за счет некоторой производительности.
для нефизического файла есть два случая,
- файл удаляется после завершения процесса.
- IIS не работает в том же пользователе, что и процесс консоли, IIS работает в ограниченном режиме, поэтому, если вы не создадите файл с добавленной безопасностью, чтобы разрешить процессу доступ к вашей службе.
вам придется использовать http://msdn.microsoft.com/en-us/library/dd267529 (v=против 110).aspx этот конструктор со следующим безопасность.
MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity ();
mSec.AddAccessRule(new AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
MemoryMappedFileRights .FullControl, AccessControlType.Allow));
а затем попробуйте получить к нему доступ из IIS с той же безопасностью.