222 lines
8.9 KiB
C#
222 lines
8.9 KiB
C#
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;
|
||
/// <summary>
|
||
/// 写共享内存
|
||
/// </summary>
|
||
/// <param name="structSize">需要映射的文件的字节数量</param>
|
||
/// <param name="obj">映射对象(简单类型、结构体等)</param>
|
||
/// <param name="fileName">文件映射对象的名称</param>
|
||
/// <returns></returns>
|
||
public static int WriteToMemory(uint structSize, Object obj, string fileName)
|
||
{
|
||
return WriteToMemory(structSize, obj, fileName, null, 0);
|
||
}
|
||
/// <summary>
|
||
/// 写共享内存
|
||
/// </summary>
|
||
/// <param name="structSize">需要映射的文件的字节数量</param>
|
||
/// <param name="obj">映射对象(简单类型、结构体等)</param>
|
||
/// <param name="fileName">文件映射对象的名称</param>
|
||
/// <param name="windowName">发送消息的窗口句柄</param>
|
||
/// <param name="Msg">发送消息</param>
|
||
/// <returns></returns>
|
||
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
|
||
// Msg.ShowMsg("创建共享内存失败" + publicInfo.GetLastError().ToString());
|
||
return -2;
|
||
}
|
||
else
|
||
{
|
||
if (ERROR_ALREADY_EXISTS == GetLastError())
|
||
{
|
||
//共享内存已经存在,记log
|
||
//Msg.ShowMsg("共享内存已经存在");
|
||
return -3;
|
||
}
|
||
}
|
||
hVoid = MapViewOfFile(hShareMemoryHandle, FILE_MAP_WRITE, 0, 0, structSize);
|
||
if (hVoid == IntPtr.Zero)
|
||
{
|
||
CloseHandle(hShareMemoryHandle);
|
||
//文件映射失败,记log
|
||
//Msg.ShowMsg("文件映射失败");
|
||
return -4;
|
||
}
|
||
Marshal.StructureToPtr(obj, hVoid, false);
|
||
//发送消息,通知接收
|
||
if (windowName != null)
|
||
{
|
||
IntPtr handle = FindWindow(null, windowName.Trim());
|
||
if (handle == IntPtr.Zero)
|
||
{
|
||
//查找窗口失败,记log
|
||
//Msg.ShowMsg("查找窗口失败");
|
||
return -5;
|
||
}
|
||
else
|
||
{
|
||
if (PostMessage(handle, (uint)Msg, 0, 0))
|
||
{
|
||
//发送消息成功
|
||
//Msg.ShowMsg("写共享内存,通知发送消息成功");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//参数不合法,记log
|
||
//Msg.ShowMsg("共享内存已经存在");
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
/// <summary>
|
||
/// 读共享内存
|
||
/// </summary>
|
||
/// <param name="structSize">需要映射的文件的字节数量</param>
|
||
/// <param name="type">类型</param>
|
||
/// <param name="fileName">文件映射对象的名称</param>
|
||
/// <returns>返回读到的映射对象</returns>
|
||
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
|
||
//Msg.ShowMsg("打开共享内存失败:" + publicInfo.GetLastError().ToString());
|
||
return null;
|
||
}
|
||
hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize);
|
||
if (hVoid == IntPtr.Zero)
|
||
{
|
||
//文件映射失败,记log
|
||
// Msg.ShowMsg("文件映射失败——读共享内存");
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 读共享内存
|
||
/// </summary>
|
||
/// <param name="structSize">需要映射的文件的字节数量</param>
|
||
/// <param name="type">类型</param>
|
||
/// <param name="fileName">文件映射对象的名称</param>
|
||
/// <returns>返回读到的映射字节数据</returns>
|
||
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
|
||
//Msg.ShowMsg("打开共享内存失败:" + publicInfo.GetLastError().ToString());
|
||
return null;
|
||
}
|
||
hVoid = MapViewOfFile(hMappingHandle, FILE_MAP_READ, 0, 0, structSize);
|
||
if (hVoid == IntPtr.Zero)
|
||
{
|
||
//文件映射失败,记log
|
||
//Msg.ShowMsg("文件映射失败——读共享内存");
|
||
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;
|
||
}
|
||
}
|
||
}
|