我針對.NET Framework 3.5的發現(4.0+可悲的是不是這個項目的一個選項)在64位的Windows 8,我原本以爲問題是,由ProcessA作出的內存映射文件不容易找到的進程B,但即使不ProcessA可以找到剛纔保存的文件,即使手感好,可用於書寫和讀取文件。在代碼示例中,我在調用CreateFileMapping之後立即調用OpenFileMapping,但即使在將數據寫入文件之後它仍然失敗。我已經使用了與文件映射的CreateFileMapping屬性,使其長傳入0,使其成爲一個SECURITY_ATTRIBUTES結構和IntPtr.Zero傳遞的lpSecurityDescriptor,都沒有快樂。我也嘗試過FileMapAccess ReadWrite和AllAccess。我也試着讓memoryfilename不是常量。我沒有看到爲什麼無法找到映射文件,甚至無法找到創建映射文件的過程。這裏所涉及的代碼的梗概:內存映射文件不能用,只是創建它的進程
private IntPtr hHandle;
private IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
public const Int64 FILESIZE = 1024 * 1024;
private const string memoryfilename = "myfilename";
//CreateFileMapping
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFileMapping(
IntPtr hFile,
IntPtr lpFileMappingAttributes,
FileMapProtection flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow,
[MarshalAs(UnmanagedType.LPStr)] string lpName);
//OpenFileMapping
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenFileMapping(
FileMapAccess dwDesiredAccess,
Int32 bInheritHandle,
[MarshalAs(UnmanagedType.LPStr)] string lpName);
[Flags]
public enum FileMapAccess : uint
{
FileMapCopy = 0x0001,
FileMapWrite = 0x0002,
FileMapRead = 0x0004,
FileMapReadWrite = 0x0006,
FileMapAllAccess = 0x001f,
FileMapExecute = 0x0020,
}
[Flags]
enum FileMapProtection : uint
{
PageReadonly = 0x02,
PageReadWrite = 0x04,
PageWriteCopy = 0x08,
PageExecuteRead = 0x20,
PageExecuteReadWrite = 0x40,
SectionCommit = 0x8000000,
SectionImage = 0x1000000,
SectionNoCache = 0x10000000,
SectionReserve = 0x4000000,
}
//hHandle becomes non-zero
hHandle= CreateFileMapping(
INVALID_HANDLE_VALUE, IntPtr.Zero, FileMapProtection.PageReadWrite,
(uint)0, (uint)FILESIZE, memoryfilename);
//hHandle2 stays zero
IntPtr hHandle2 = OpenFileMapping(FileMapAccess.FileMapWrite, 0, memoryfilename);
//myerror is 2 ERROR_FILE_NOT_FOUND
uint myerror = GetLastError();
//this works and I can read/write the file through UnmanagedMemoryStream
pBuffer = MapViewOfFile(hHandle, FileMapAccess.FileMapWrite, 0, 0, (uint)FILESIZE);
您的標註聲明非常漂亮。最嚴重的錯誤是在您的CreateFileMapping()聲明中,它會創建一箇中文名稱的MMF。刪除[MarshalAs]。使用pinvoke.net網站以取得進展。 –
@HansPassant這裏就屬於這種情況,正如經常出現的方式,用pinvoke.net讓後面的。 Q中的p/invoke來自那裏!我只是修復它。 pinvoke.net是非常可怕的。也許我們應該找一些專家來整理一個正確的選擇。花時間寫出權威指南來與我聯繫? ;-) –
你說得對,漢斯!不幸的是,CreateFileMapping和OpenFileMapping的pinvoke示例(我使用過)通過免費將字符串封裝爲LPStr而打破了這個例子。謝謝! –