VSoft/Source/DyLine/ryMemoryShare.cs
如果当时 2e557b5365 ### 2021-02-27更新
------
#### VSoft    V1.0.2102.2701
- *.[新增]全新的UI,更加美观。
2021-02-27 22:49:54 +08:00

222 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}