Asp.net 在IIS中部署时,打开内存映射文件会导致FileNotFoundException

Asp.net 在IIS中部署时,打开内存映射文件会导致FileNotFoundException,asp.net,.net,iis,ipc,memory-mapped-files,Asp.net,.net,Iis,Ipc,Memory Mapped Files,按照网站中的代码示例,我创建了一个windows控制台应用程序,该应用程序创建了一个映射内存文件: using (var file = MemoryMappedFile.CreateNew("myFile", 24)) { var bytes = new byte[24]; for (var i = 0; i < bytes.Length; i++) bytes[i] = (by

按照网站中的代码示例,我创建了一个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();
        }
使用(var file=MemoryMappedFile.CreateNew(“myFile”,24))
{
var字节=新字节[24];
for(var i=0;i
在新的asp.net web应用程序中,我使用以下代码读取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);
    }
受保护的无效页面加载(对象发送方,事件参数e)
{
字符串sOutput=“”;
使用(var file=MemoryMappedFile.OpenExisting(“myFile”))
{
使用(var reader=file.CreateViewAccessor(0,24))
{
var字节=新字节[24];
reader.ReadArray(0,字节,0,字节.长度);
for(var i=0;i
在开发IIS Express中,文件按预期读取,页面显示映射内存文件中的数据

但是,当部署到IIS时,我在位置
MemoryMappedFile.OpenExisting(“myFile”)
处获得异常
System.IO.FileNotFoundException


我尝试将应用程序池标识更改为运行MMF控制台应用程序的标识,但没有成功

对于非物理文件,有两种情况

  • 进程退出后,文件将被删除
  • IIS和您的控制台进程不在同一个用户中运行,IIS在小限制模式下运行,所以除非您创建具有附加安全性的文件以允许进程访问您的服务
  • 您必须使用具有以下安全性的构造函数

            MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity ();
            mSec.AddAccessRule(new AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                MemoryMappedFileRights .FullControl, AccessControlType.Allow));
    
    MemoryMappedFileSecurity mSec=newmemorymappedfilesecurity();
    mSec.AddAccessRule(新的AccessRule(新的SecurityIdentifier)(WellKnownSidType.WorldSid,null),
    MemoryMappedFileRights.FullControl、AccessControlType.Allow);
    

    然后尝试以相同的安全性从IIS访问它。

    如果进程间通信(IPC)是您试图实现的,则可以将WCF与命名管道绑定一起使用。您以牺牲一些性能为代价获得了许多简单性。

    在地图名称中添加“Global\\”前缀。这是唯一对我有效的方法。
            MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity ();
            mSec.AddAccessRule(new AccessRule<MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                MemoryMappedFileRights .FullControl, AccessControlType.Allow));
    
    当我们尝试访问在第一个进程中创建的共享内存时,它运行在不同的安全上下文中,共享内存对象不可见,除非它们是在全局命名空间中创建的

    这是对我有用的代码。我在WinForm应用程序中使用CreateOrOpen,在IIS进程中使用OpenExisting:

    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");
    
    mSec=newmemorymappedFileSecurity();
    mSec.AddAccessRule(新的AccessRule(新的SecurityIdentifier(WellKnownSidType.WorldSid,null)、MemoryMappedFilers.FullControl、AccessControlType.Allow));
    mmf=MemoryAppedFile.CreateOrOpen(“全局\\\MmfName”,100,MemoryAppedFileAccess.ReadWrite,MemoryAppedFileOptions.None,mSec,HandleInheritability.Inheritable);
    mmf=MemoryMappedFile.OpenExisting(“全局\\\MmfName”);
    
    myFile位于何处?ISAPI模块是否安装在生产IIS上?在
    Page\u Load
    中,您正在调用
    MemoryMappedFile.OpenExisting
    。但是在web应用程序中是否有
    MemoryMappedFile.CreateNew
    方法调用?在创建MMF的控制台应用程序中调用
    CreateNew
    。当console应用程序运行时,您可以从另一个进程访问MMF。使用IIS Express时会出现这种情况,但尚未安装标准IISISAPI模块。默认文件夹位于\windows\system32或\windows\system32\inetsrv中。您需要指定完整路径,如此答案所示,或者调用Server.MapPath(“~/myFile.txt”)根据您的web应用程序计算它。myFile只是内存映射文件的名称,它在磁盘afaik上没有可访问的物理位置,而且,myFile引用是由另一个windows进程创建的(在我的示例中,它只是一个小型控制台应用程序)。当网站在IIS Express中运行时,它可以访问映射的内存位置。当我将Visual Studio设置为使用本地IIS时,它会失败。内存映射文件必须是磁盘上的物理位置,您在哪里读到它不一定是?“文件”表示它是磁盘上的一个物理位置,否则您无论如何都有内存。我使用的是描述为“CreateNew和CreateOrOpen方法创建的内存映射文件未映射到磁盘上的现有文件”的非持久内存映射文件仍然没有乐趣。我创建了MMF以在
    NetworkService
    的上下文中运行,并将IIS工作进程的标识设置为相同的,但我仍然得到
    无法找到指定的文件。
    异常。由于我最初的帖子,这实际上是我走过的路,它工作得非常好。这是一种解决方法,而不是解决方案。将此作为答案是错误的,因为它不会帮助将来可能需要此问题解决方案的任何其他人。我将代码稍微更改为
    MemoryMappedFile.OpenExisting(“Global\\myFile”,MemoryMappedFileRights.FullControl,System.IO.HandleInheritability.None)
    ,这似乎成功了。非常感谢。