Открытие сопоставленного с памятью файла вызывает 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 с привязкой именованного канала. Вы получаете много простоты за счет некоторой производительности.


для нефизического файла есть два случая,

  1. файл удаляется после завершения процесса.
  2. 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 с той же безопасностью.