来源程序 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices;namespace WMCopyDataA { public partial class Form1 : Form { public Form1() { InitializeComponent(); } [StructLayout(LayoutKind.Sequential)] public struct CopyDataStruct { public int dwData; // 附加参数 public int cbData; // 数据大小 public IntPtr lpData; // 数据内容 } public const int WM_COPYDATA = 0x004A; [DllImport("user32.dll")] public static extern bool SendMessage( IntPtr hWnd, int Msg, int wParam, int lParam); private void button1_Click(object sender, EventArgs e) { string S = textBox1.Text; if (S.Length <= 0) { Console.WriteLine("内容为空"); return; } Process[] vProcesses = Process.GetProcessesByName("WMCopyDataB"); // 查询目标进程 if (vProcesses.Length <= 0) vProcesses = Process.GetProcessesByName("WMCopyDataB.vshost"); // 处理调试运行 if (vProcesses.Length <= 0) { Console.WriteLine("目标进程没有找到"); return; } CopyDataStruct vCopyDataStruct = new CopyDataStruct(); vCopyDataStruct.dwData = 0; vCopyDataStruct.cbData = S.Length * sizeof(char) + sizeof(char); // 最后结束字符\x00 vCopyDataStruct.lpData = Marshal.StringToBSTR(S); IntPtr vAddress = Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct)); Marshal.StructureToPtr(vCopyDataStruct, vAddress, true); foreach (Process vProcess in vProcesses) { SendMessage(vProcess.MainWindowHandle, WM_COPYDATA, 0, (int)vAddress); // 发送结构 } Marshal.FreeBSTR(vCopyDataStruct.lpData); Marshal.FreeCoTaskMem(vAddress); } } }目标程序 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices;namespace WMCopyDataB { public partial class Form1 : Form { public Form1() { InitializeComponent(); } [StructLayout(LayoutKind.Sequential)] public struct CopyDataStruct { public int dwData; // 附加参数 public int cbData; // 数据大小 public IntPtr lpData; // 数据内容 } public const int WM_COPYDATA = 0x004A; protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_COPYDATA: CopyDataStruct vCopyDataStruct = (CopyDataStruct)Marshal.PtrToStructure( m.LParam, typeof(CopyDataStruct)); string S = Marshal.PtrToStringBSTR(vCopyDataStruct.lpData); textBox1.Text = S; break; } base.WndProc(ref m); } } }
传送Object对象的时候就会出现问题。 [StructLayout(LayoutKind.Sequential)] public struct CopyDataStruct { public int dwData; // 附加参数 public object data; //传送的数据 public int cbData; // 数据大小 public IntPtr lpData; // 数据内容 <--比这个大 } 这样写这个CopyDataStruct 类,程序就会出错。何解???请指教!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;namespace WMCopyDataA
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public int dwData; // 附加参数
public int cbData; // 数据大小
public IntPtr lpData; // 数据内容
} public const int WM_COPYDATA = 0x004A; [DllImport("user32.dll")]
public static extern bool SendMessage(
IntPtr hWnd, int Msg, int wParam, int lParam); private void button1_Click(object sender, EventArgs e)
{
string S = textBox1.Text;
if (S.Length <= 0)
{
Console.WriteLine("内容为空");
return;
}
Process[] vProcesses = Process.GetProcessesByName("WMCopyDataB"); // 查询目标进程 if (vProcesses.Length <= 0)
vProcesses = Process.GetProcessesByName("WMCopyDataB.vshost"); // 处理调试运行 if (vProcesses.Length <= 0)
{
Console.WriteLine("目标进程没有找到");
return;
}
CopyDataStruct vCopyDataStruct = new CopyDataStruct();
vCopyDataStruct.dwData = 0;
vCopyDataStruct.cbData = S.Length * sizeof(char) + sizeof(char); // 最后结束字符\x00
vCopyDataStruct.lpData = Marshal.StringToBSTR(S);
IntPtr vAddress = Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct));
Marshal.StructureToPtr(vCopyDataStruct, vAddress, true);
foreach (Process vProcess in vProcesses)
{
SendMessage(vProcess.MainWindowHandle, WM_COPYDATA, 0, (int)vAddress); // 发送结构
}
Marshal.FreeBSTR(vCopyDataStruct.lpData);
Marshal.FreeCoTaskMem(vAddress);
}
}
}目标程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace WMCopyDataB
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} [StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public int dwData; // 附加参数
public int cbData; // 数据大小
public IntPtr lpData; // 数据内容
} public const int WM_COPYDATA = 0x004A; protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
CopyDataStruct vCopyDataStruct = (CopyDataStruct)Marshal.PtrToStructure(
m.LParam, typeof(CopyDataStruct)); string S = Marshal.PtrToStringBSTR(vCopyDataStruct.lpData);
textBox1.Text = S;
break;
}
base.WndProc(ref m);
}
}
}
“只能发送String、Char等等”?WM_COPYDATA传递的是一个缓冲区,照你这样说内存里只能存放String、Char等等了。
object不是单纯的数据类型,它和类及其继承类都有关系。
内存地址都是相对于自身进程的,除非自己写个操作系统用物理地址得了。
[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public int dwData; // 附加参数
public object data; //传送的数据
public int cbData; // 数据大小
public IntPtr lpData; // 数据内容 <--比这个大
}
这样写这个CopyDataStruct 类,程序就会出错。何解???请指教!
Message="未指定的错误 (异常来自 HRESULT:0x80004005 (E_FAIL))"
Source="mscorlib"
ErrorCode=-2147467259
StackTrace:
在 System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses)
在 System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Type structureType)
在 WMCopyDataB.Form1.WndProc(Message& m) 位置 I:\Code\Temp\SharMemEx\WMCopyDataB\Form1.cs:行号 36
在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
在 System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg, HandleRef hwnd, Int32 msgMin, Int32 msgMax, Int32 remove)
在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 在 System.Windows.Forms.Application.Run(Form mainForm)
在 WMCopyDataB.Program.Main() 位置 I:\Code\Temp\SharMemEx\WMCopyDataB\Program.cs:行号 17 在 System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
“只能发送String、Char等等”?WM_COPYDATA传递的是一个缓冲区,照你这样说内存里只能存放String、Char等等了。
object不是单纯的数据类型,它和类及其继承类都有关系。
内存地址都是相对于自身进程的,除非自己写个操作系统用物理地址得了。
对,因为每个进程的内存地址是相对的。
我们现在就是要在2个进程间传递数据啊。
vCopyDataStruct.lpData = Marshal.StringToBSTR(S);这句代码
Marshal.StringToBSTR这个入口参数只能是string除非我现在把要传递的数据做成XML然后Tostriing()后才可以。而且我还不知道这个XML是否有可以足够大。
因为IntPtr vAddress = Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct));
这句代码分配内存的时候,具体是多大是一个限额吧。
怎么样能自动根据我XML的大小来自动分配足够的内存。[StructLayout(LayoutKind.Sequential)]
public struct CopyDataStruct
{
public int dwData; // 附加参数
public int cbData; // 数据大小
public IntPtr lpData; // 数据内容
}
public int cbData; // 数据大小
这句代码的作用又是什么?
昵称:伴水 清洁工 看帖要回贴“少量数据”?WM_COPYDATA至少可以传递百兆以上的数据
-----------------------------------------------设置长度(参考):CopyDataStruct.cbData = [xml].ToString().Length + 1;
最好自己到MSDN去查一下WM_COPYDATA相关资料如果XML.ToString()后处理效果还行,那就凑合用。
先实际动手做一下看看效果再说。别凭空猜测效率。为提高效率可以考虑采用内存镜像文件,查CreateFileMapping的资料。
----------------
对于一个指针数据来说它又没有结束标记的。(C\C++中的char*至少还有0结束标记,可以不指定大小)
没有结束标记的数据块,除了指定其大小你还有什么更好的办法访问它?
cbData就是指lpData的大小。
-_-!!!
进程通讯有很多种,单机的网络的,有些只适用与单机,有些两者同时适用.这方面我们可以参考 微软的 sql server 的进程通讯机制,本机采用的是 共享内存(共享内存区和copy_data实质一样的),网络上采用的是 socket 和 named pipe,想来这样的效率比较好.
LZ去参考一下MSDN.
.net下不知道有没有相对应的类.