我可以获得内存映射文件的路径吗? (.NET 4.0)

我希望非.NET应用程序访问内存映射文件, 但是这个应用程序不知道内存映射文件的存在 ,所以我需要文件路径。 有可能的?

他们这里有一些样品。

编辑

我想这会提供答案。 基本上,内存映射文件似乎需要某种内存指针,而不是文件系统路径。

您可以使用GetMappedFileName函数在映射时获取内存映射文件的路径。 这当然要求内存映射文件实际上由物理文件支持,但问题是它的具体情况是模糊的。 某些第三方库是否为您提供了MemoryMappedFile,MemoryMappedViewAccessor或MemoryMappedViewStream,但您不知道它是否由物理文件支持?

这是一个示例,显示如何从MemoryMappedFile获取文件名:

using Microsoft.Win32.SafeHandles; using System; using System.ComponentModel; using System.Diagnostics; using System.IO.MemoryMappedFiles; using System.Runtime.InteropServices; using System.Text; namespace MMFilePathTest { static class Program { private static MemoryMappedFile GetMappedPhysicalFile() { return MemoryMappedFile.CreateFromFile("test.bin", System.IO.FileMode.Create, null, 4096); } private static MemoryMappedFile GetMappedAnonymousMemory() { /* The documentation errounously claims that mapName must not be null. Actually anonymous * mappings are quite a normal thing on Windows, and is actually both safer and more secure * if you don't have a need for a name for them anyways. * (Reported as https://github.com/dotnet/docs/issues/5404) * Using a name here gives the exact same results (assuming the name isn't already in use). */ return MemoryMappedFile.CreateNew(null, 4096); } /* This can be changed to kernel32.dll / K32GetMappedFileNameW if compatibility with Windows Server 2008 and * earlier is not needed, but it is not clear what the gain of doing so is, see the remarks about * PSAPI_VERSION at https://msdn.microsoft.com/en-us/library/windows/desktop/ms683195(v=vs.85).aspx */ [DllImport("Psapi.dll", EntryPoint = "GetMappedFileNameW", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)] private static extern int GetMappedFileName( SafeProcessHandle hProcess, SafeMemoryMappedViewHandle lpv, [Out] StringBuilder lpFilename, int nSize ); /* Note that the SafeMemoryMappedViewHandle property of SafeMemoryMappedViewAccess and SafeMemoryMappedViewStream * is actually the address where the file is mapped */ private static string GetPathWithGetMappedFileName(SafeMemoryMappedViewHandle memoryMappedViewHandle) { // The maximum path length in the NT kernel is 32,767 - memory is cheap nowadays so its not a problem // to just allocate the maximum size of 32KB right away. StringBuilder filename = new StringBuilder(short.MaxValue); int len; len = GetMappedFileName(Process.GetCurrentProcess().SafeHandle, memoryMappedViewHandle, filename, short.MaxValue); if (len == 0) throw new Win32Exception(Marshal.GetLastWin32Error()); filename.Length = len; return filename.ToString(); } private static void PrintFileName(MemoryMappedFile memoryMappedFile) { try { using (memoryMappedFile) using (MemoryMappedViewAccessor va = memoryMappedFile.CreateViewAccessor()) { string filename = GetPathWithGetMappedFileName(va.SafeMemoryMappedViewHandle); Console.WriteLine(filename); } } catch (Win32Exception e) { Console.WriteLine("Error: 0x{0:X08}: {1}", e.NativeErrorCode, e.Message); } } static void Main(string[] args) { PrintFileName(GetMappedPhysicalFile()); PrintFileName(GetMappedAnonymousMemory()); } } } 

当我运行这个时,我得到输出:

 \Device\HarddiskVolume5\Users\poizan\Documents\Visual Studio 2017\Projects\MMFilePathTest\MMFilePathTest\bin\Debug\test.bin Error: 0x000003EE: The volume for a file has been externally altered so that the opened file is no longer valid 

请注意,路径以本机NT路径格式返回。 如果您需要将其转换为dos / win32格式,请参阅此问题: 如何将本机(NT)路径名转换为Win32路径名?

对于没有文件关联时的错误,错误消息有点奇怪,但错误代码意味着ERROR_FILE_INVALID ,这是有道理的,因为没有文件。