我正在尝试使用内存映射文件为IPC编写简单的发送器/接收器类。 我的代码中存在问题,但我不明白我在这里做错了什么:
[Serializable]
public struct MessageData
{
public int PID;
public IntPtr HWND;
public string ProcessName;
public string ProcessTitle;
}
....
public static class MMF
{
private const int MMF_MAX_SIZE = 4096; // allocated memory for this memory mapped file (bytes)
private const int MMF_VIEW_SIZE = 4096; // how many bytes of the allocated memory can this process access
public static void Write()
{
var security = new MemoryMappedFileSecurity();
// Create a SecurityIdentifier object for "everyone".
SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(new AccessRule<MemoryMappedFileRights>(everyoneSid, MemoryMappedFileRights.FullControl, AccessControlType.Allow));
using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("Global\\mmf1", MMF_MAX_SIZE, MemoryMappedFileAccess.ReadWrite))
{
using (MemoryMappedViewStream mStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE))
{
var p = Process.GetCurrentProcess();
MessageData msgData = new MessageData();
msgData.HWND = p.MainWindowHandle;
msgData.PID = p.Id;
msgData.ProcessName = p.ProcessName;
msgData.ProcessTitle = p.MainWindowTitle;
// serialize the msgData and write it to the memory mapped file
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(mStream, msgData);
mStream.Flush();
mStream.Seek(0, SeekOrigin.Begin); // sets the current position back to the beginning of the stream
//MessageBox.Show("Done");
}
}
}
}
现在我尝试从主应用程序表单测试此代码:
...
private void button1_Click(object sender, EventArgs e)
{
MMF.Write();
}
Visual Studio 2015社区中的流程依然存在。进程运行,但表单界面没有响应。我只能暂停或停止进程。这是using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("Global\\mmf1", ...
字符串停止的。
我假设应用无法创建文件,但没有任何例外。
因此,如果我将地图名称更改为“mmf1”(没有“全局”前缀),一切正常,应用程序正常。但据我所知,this answer和MSDN:
使用“Global \”前缀文件映射对象名称允许进程相互通信,即使它们位于不同的终端服务器会话中。
如果我理解正确,则需要使用前缀“Global \”来将我的内存映射文件与任何应用程序进行交互,无论它们运行的权限如何。
特别是因为我正在尝试为“所有人”设置文件访问权限。
UPD。此代码在Win 7 / Win 8.1 x64上进行了测试。结果是一样的。
答案 0 :(得分:1)
您必须以管理员身份运行Visual Studio才能使用“Global \”前缀创建内存映射文件。