using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ryCommon.Model
{
public class ryMemoryShare
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr OpenFileMapping(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32", EntryPoint = "GetLastError")]
private static extern int GetLastError();
[DllImport("user32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
private static extern bool PostMessage(IntPtr hWnd, uint uMsg, int wParam, int lParam);
const int ERROR_ALREADY_EXISTS = 183;
const int FILE_MAP_COPY = 0x0001;
const int FILE_MAP_WRITE = 0x0002;
const int FILE_MAP_READ = 0x0004;
const int FILE_MAP_ALL_ACCESS = 0x0002 | 0x0004;
const int PAGE_READONLY = 0x02;
const int PAGE_READWRITE = 0x04;
const int PAGE_WRITECOPY = 0x08;
const int PAGE_EXECUTE = 0x10;
const int PAGE_EXECUTE_READ = 0x20;
const int PAGE_EXECUTE_READWRITE = 0x40;
const int SEC_COMMIT = 0x8000000;
const int SEC_IMAGE = 0x1000000;
const int SEC_NOCACHE = 0x10000000;
const int SEC_RESERVE = 0x4000000;
const int INVALID_HANDLE_VALUE = -1;
///
/// 写共享内存
///
/// 需要映射的文件的字节数量
/// 映射对象(简单类型、结构体等)
/// 文件映射对象的名称
///
public static int WriteToMemory(uint structSize, Object obj, string fileName)
{
return WriteToMemory(structSize, obj, fileName, null, 0);
}
///
/// 写共享内存
///
/// 需要映射的文件的字节数量
/// 映射对象(简单类型、结构体等)
/// 文件映射对象的名称
/// 发送消息的窗口句柄
/// 发送消息
///
public static int WriteToMemory(uint structSize, Object obj, string fileName, string windowName, uint Msg)
{
IntPtr hShareMemoryHandle = IntPtr.Zero;
IntPtr hVoid = IntPtr.Zero;
//判断参数的合法性
if (structSize > 0 && fileName.Length > 0)
{
hShareMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, (uint)PAGE_READWRITE, 0, (uint)structSize, fileName);
if (hShareMemoryHandle == IntPtr.Zero)
{
//创建共享内存失败,记log
// MessageBox.Show("创建共享内存失败" + publicInfo.GetLastError().ToString());
return -2;
}
else
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
//共享内存已经存在,记log
//MessageBox.Show("共享内存已经存在");
return -3;
}
}
hVoid = MapViewOfFile(hShareMemoryHandle, FILE_MAP_WRITE, 0, 0, structSize);
if (hVoid == IntPtr.Zero)
{
CloseHandle(hShareMemoryHandle);
//文件映射失败,记log
//MessageBox.Show("文件映射失败");
return -4;
}
Marshal.StructureToPtr(obj, hVoid, false);
//发送消息,通知接收
if (windowName != null)
{
IntPtr handle = FindWindow(null, windowName.Trim());
if (handle == IntPtr.Zero)
{
//查找窗口失败,记log
//MessageBox.Show("查找窗口失败");
return -5;
}
else
{
if (PostMessage(handle, (uint)Msg, 0, 0))
{
//发送消息成功
//MessageBox.Show("写共享内存,通知发送消息成功");
}
}
}
}
else
{
//参数不合法,记log
//MessageBox.Show("共享内存已经存在");
return -1;
}
return 0;
}
///
/// 读共享内存
///
/// 需要映射的文件的字节数量
/// 类型
/// 文件映射对象的名称
/// 返回读到的映射对象
public static Object ReadFromMemory(uint structSize, Type type, string fileName)
{
IntPtr hMappingHandle = IntPtr.Zero;
IntPtr hVoid = IntPtr.Zero;
hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName);
if (hMappingHandle == IntPtr.Zero)
{
//打开共享内存失败,记log
//MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString());
return null;
}
hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize);
if (hVoid == IntPtr.Zero)
{
//文件映射失败,记log
// MessageBox.Show("文件映射失败——读共享内存");
return null;
}
Object obj = Marshal.PtrToStructure(hVoid, type);
if (hVoid != IntPtr.Zero)
{
UnmapViewOfFile(hVoid);
hVoid = IntPtr.Zero;
}
if (hMappingHandle != IntPtr.Zero)
{
CloseHandle(hMappingHandle);
hMappingHandle = IntPtr.Zero;
}
return obj;
}
///
/// 读共享内存
///
/// 需要映射的文件的字节数量
/// 类型
/// 文件映射对象的名称
/// 返回读到的映射字节数据
public static byte[] ReadFromMemory2(uint structSize, Type type, string fileName)
{
IntPtr hMappingHandle = IntPtr.Zero;
IntPtr hVoid = IntPtr.Zero;
hMappingHandle = OpenFileMapping((uint)FILE_MAP_READ, false, fileName);
if (hMappingHandle == IntPtr.Zero)
{
//打开共享内存失败,记log
//MessageBox.Show("打开共享内存失败:" + publicInfo.GetLastError().ToString());
return null;
}
hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize);
if (hVoid == IntPtr.Zero)
{
//文件映射失败,记log
//MessageBox.Show("文件映射失败——读共享内存");
return null;
}
//Object obj = Marshal.PtrToStructure(hVoid, type);
byte[] bytes = new byte[structSize];
Marshal.Copy(hVoid, bytes, 0, bytes.Length);
if (hVoid != IntPtr.Zero)
{
UnmapViewOfFile(hVoid);
hVoid = IntPtr.Zero;
}
if (hMappingHandle != IntPtr.Zero)
{
CloseHandle(hMappingHandle);
hMappingHandle = IntPtr.Zero;
}
return bytes;
}
}
}