进程间通讯—自定义消息
自定义消息WM_COPYDATA,使用sendMessage发送消息
最近想实现进程间通讯,遇到一些问题记录一下。
发送方:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam); //发送消息
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string lpWindowName); //获取窗体的hwnd
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT //自定义结构
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
public const int USER = 0x500; // 自定义消息的rang 0x0400-0x7FFF
const int WM_USER_COPYDATA = USER + 1;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = "E:\\WYP\\资源\\lover.mp4";
cds.cbData = len + 1;
SendMessage(hwnd, WM_USER_COPYDATA, 0, ref cds);
(1)本想传递一个字符串参数到接收方,定义一个结构传递一个字符串。
接收方:
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
case WM_USER_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr =(COPYDATASTRUCT)m.GetLParam(mytype)
string str=mystr.LParam; //这个为空。
}
}
(2)用自定义结构接收不到字符串,然后我就想用共享内存。
然后用到了marshal.copy()方法 发现marshal只能用在一个进程中。
Marshal.Copy(m_pwData, bytData, 0, infoSize); //将数据从非托管内存指针复制到托管 8 位无符号整数数组。
Marshal.Copy(bytData, 0, m_pwDataWrite, lngSize); //将一维的托管 8 位无符号整数数组中的数据复制到非托管内存指针。
(3)然后我又想在发送方进程中申请一个内存空间,目标进程收到传来的内存地址,读取内存,最后释放内存。
发送发:
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)] //创建内存共享体
public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, uint flProtect, uint dwMaxSizeHi, uint dwMaxSizeLow, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)] //打开文件映射
public static extern IntPtr OpenFileMapping(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, string lpName);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)] //创建内存映射
public static extern IntPtr MapViewOfFile(IntPtr hFileMapping, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, uint dwNumberOfBytesToMap);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)] //关闭共享内存
public static extern bool UnmapViewOfFile(IntPtr pvBaseAddress);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle); // 调用closehandle(HANDLE)表示创建者放弃对该内核对象的操作。如果该对象的引用对象记数为0就撤消该对象。
......待写。。。