public static extern bool CloseHandle(IntPtr handle);
我们在示例里Server端建立的一个FileMapping,命名为:@"Global\MyFileMappingObject";这样我们在Client端就可以打开同名的FileMapping,这样在Server和Client之前进行通信。每次Server将数据写入后,我们通过Message的方式通知Client端数据已经准备好,可以读取了。(关于Message我们之前说过,不在细说。)
具体看一下代码:
在看具体的代码这之前,先看一下其中用到的一些常量定义:
[Flags]
public enum MapProtection
{
PageNone = 0x00000000,
// protection - mutually exclusive, do not or
PageReadOnly = 0x00000002,
PageReadWrite = 0x00000004,
PageWriteCopy = 0x00000008,
// attributes - or-able with protection
SecImage = 0x01000000,
SecReserve = 0x04000000,
SecCommit = 0x08000000,
SecNoCache = 0x10000000,
}
public enum MapAccess
{
FileMapCopy = 0x0001,
FileMapWrite = 0x0002,
FileMapRead = 0x0004,
FileMapAllAccess = 0x001f,
}
public const short FILE_ATTRIBUTE_NORMAL = 0x80;
public const short INVALID_HANDLE_VALUE = -1;
public const uint GENERIC_READ = 0x80000000;
public const uint GENERIC_WRITE = 0x40000000;
public const uint FILE_SHARE_READ = 0x00000001;
public const uint CREATE_NEW = 1;
public const uint CREATE_ALWAYS = 2;
public const uint OPEN_EXISTING = 3;
Windows Message:
public const int WM_USER = 0x0400;
public const int WM_USER_DATAREADY = WM_USER + 101;
下边是Server端的:
创建MapView:
IntPtr.Zero, IntPtr.Zero,
(int)(MapProtection.PageReadWrite | MapProtection.SecCommit),
0, 1000000, Win32Wrapper.MappingFileName);
mappingHandle = Win32Wrapper.MapViewOfFile(
fileHandle, (int)MapAccess.FileMapWrite, 0, 0, new IntPtr(1024));
if (mappingHandle == IntPtr.Zero)
{
MessageBox.Show("Open mapping file failed!");
}
写入信息并通知Client端:
private void btnSend_Click(object sender, EventArgs e)
{
//Write message
string message = string.IsNullOrEmpty(this.sendTxt.Text)
"no message" : this.sendTxt.Text;
byte[] source = Encoding.ASCII.GetBytes(message);
byte[] msg = new byte[1024];
Array.Copy(source, msg, source.Length);
Marshal.Copy(msg, 0, mappingHandle, msg.Length);
Win32Wrapper.FlushViewOfFile(mappingHandle, new IntPtr(1024));
//Send message to client
IntPtr handle = GetClientMainFormHandle();
if (handle != IntPtr.Zero)
Win32Wrapper.SendMessage(
handle, Win32Wrapper.WM_USER_DATAREADY,
IntPtr.Zero, IntPtr.Zero);
}
得到Client端主窗体句柄的代码:
private IntPtr GetClientMainFormHandle()
{
string name =
@"CSharp.MultiProcess.Communication.FileMappingClient";
Process process = GetProcessByName(name);
return process.MainWindowHandle;
}
private Process GetProcessByName(string processName)
{
Process[] processes = Process.GetProcesses();
foreach (Process p in processes)
{
//just for debug
//this method has some question because
//the visual studio started process name
//is not