问题描述
需要在多个进程传输数据,其实一个检测进程一直获取检测的数据,供其他进程及时读取使用,数据库不是很大,但是数据更新非常的频繁,考虑到效率问题,不知道用什么方法实现?暂时决定采用内存共享的方式实现。希望各位大虾多加指点。具体怎么实现比较好?需要注意哪些地方?如果有类似的源代码参考就最好了。
解决方案
解决方案二:
方案1、使用WM_COPYDATA消息方案2、使用WriteProcessMemory(),ReadProcessMemory()访问其他进程的内存方案3、使用内存镜像文件
解决方案三:
补充说明,是单机版程序。
解决方案四:
来源程序usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Diagnostics;usingSystem.Runtime.InteropServices;namespaceWMCopyDataA{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}[StructLayout(LayoutKind.Sequential)]publicstructCopyDataStruct{publicintdwData;//附加参数publicintcbData;//数据大小publicIntPtrlpData;//数据内容}publicconstintWM_COPYDATA=0x004A;[DllImport("user32.dll")]publicstaticexternboolSendMessage(IntPtrhWnd,intMsg,intwParam,intlParam);privatevoidbutton1_Click(objectsender,EventArgse){stringS=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;}CopyDataStructvCopyDataStruct=newCopyDataStruct();vCopyDataStruct.dwData=0;vCopyDataStruct.cbData=S.Length*sizeof(char)+sizeof(char);//最后结束字符x00vCopyDataStruct.lpData=Marshal.StringToBSTR(S);IntPtrvAddress=Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct));Marshal.StructureToPtr(vCopyDataStruct,vAddress,true);foreach(ProcessvProcessinvProcesses){SendMessage(vProcess.MainWindowHandle,WM_COPYDATA,0,(int)vAddress);//发送结构}Marshal.FreeBSTR(vCopyDataStruct.lpData);Marshal.FreeCoTaskMem(vAddress);}}}
目标程序usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Runtime.InteropServices;namespaceWMCopyDataB{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}[StructLayout(LayoutKind.Sequential)]publicstructCopyDataStruct{publicintdwData;//附加参数publicintcbData;//数据大小publicIntPtrlpData;//数据内容}publicconstintWM_COPYDATA=0x004A;protectedoverridevoidWndProc(refMessagem){switch(m.Msg){caseWM_COPYDATA:CopyDataStructvCopyDataStruct=(CopyDataStruct)Marshal.PtrToStructure(m.LParam,typeof(CopyDataStruct));stringS=Marshal.PtrToStringBSTR(vCopyDataStruct.lpData);textBox1.Text=S;break;}base.WndProc(refm);}}}
解决方案五:
跑过.学习...马上我也要用到
解决方案六:
顺便问问...少量数据时用WM_COPYDATA消息处理的确很方便...但是发送的数据类型很有限,貌似只能发送String、Char等等.以前尝试过想将整个Object发送,但是最终失败收场...请问zswang有没有办法把Object对象发送到目标进程窗口???前提,两个程序都引用了这个Object类型的...^o^
解决方案七:
要求用WM_COPYDATA消息完成...
解决方案八:
学习,学习。
解决方案九:
“少量数据”?WM_COPYDATA至少可以传递百兆以上的数据“只能发送String、Char等等”?WM_COPYDATA传递的是一个缓冲区,照你这样说内存里只能存放String、Char等等了。object不是单纯的数据类型,它和类及其继承类都有关系。内存地址都是相对于自身进程的,除非自己写个操作系统用物理地址得了。
解决方案十:
呵呵...那么Object只能先序列化再传递吗???^o^
解决方案十一:
传送Object对象的时候就会出现问题。[StructLayout(LayoutKind.Sequential)]publicstructCopyDataStruct{publicintdwData;//附加参数publicobjectdata;//传送的数据publicintcbData;//数据大小publicIntPtrlpData;//数据内容<--比这个大}
这样写这个CopyDataStruct类,程序就会出错。何解???请指教!
解决方案十二:
如果加上的话。异常信息如下:未处理System.Runtime.InteropServices.COMExceptionMessage="未指定的错误(异常来自HRESULT:0x80004005(E_FAIL))"Source="mscorlib"ErrorCode=-2147467259StackTrace:在System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtrptr,Objectstructure,BooleanallowValueClasses)在System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtrptr,TypestructureType)在WMCopyDataB.Form1.WndProc(Message&m)位置I:CodeTempSharMemExWMCopyDataBForm1.cs:行号36在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtrhWnd,Int32msg,IntPtrwparam,IntPtrlparam)在System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG&msg,HandleRefhwnd,Int32msgMin,Int32msgMax,Int32remove)在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32dwComponentID,Int32reason,Int32pvLoopData)在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32reason,ApplicationContextcontext)在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32reason,ApplicationContextcontext)在System.Windows.Forms.Application.Run(FormmainForm)在WMCopyDataB.Program.Main()位置I:CodeTempSharMemExWMCopyDataBProgram.cs:行号17在System.AppDomain.nExecuteAssembly(Assemblyassembly,String[]args)在System.AppDomain.ExecuteAssembly(StringassemblyFile,EvidenceassemblySecurity,String[]args)在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()在System.Threading.ThreadHelper.ThreadStart_Context(Objectstate)在System.Threading.ExecutionContext.Run(ExecutionContextexecutionContext,ContextCallbackcallback,Objectstate)在System.Threading.ThreadHelper.ThreadStart()
解决方案十三:
Remoting
解决方案十四:
mark
解决方案十五:
某年月日,小白到此一游
解决方案:
我已经说过了,对象不是简单的数据,它依赖其所属类。对象所属类中记录了各个字段、方法、属性的内存访问地址。而这些地址在其他进程里就失效了。因为每个进程的内存地址是相对的。
解决方案:
先序列化
解决方案:
“少量数据”?WM_COPYDATA至少可以传递百兆以上的数据“只能发送String、Char等等”?WM_COPYDATA传递的是一个缓冲区,照你这样说内存里只能存放String、Char等等了。object不是单纯的数据类型,它和类及其继承类都有关系。内存地址都是相对于自身进程的,除非自己写个操作系统用物理地址得了。对,因为每个进程的内存地址是相对的。我们现在就是要在2个进程间传递数据啊。vCopyDataStruct.lpData=Marshal.StringToBSTR(S);
这句代码Marshal.StringToBSTR这个入口参数只能是string除非我现在把要传递的数据做成XML然后Tostriing()后才可以。而且我还不知道这个XML是否有可以足够大。因为IntPtrvAddress=Marshal.AllocCoTaskMem(Marshal.SizeOf(vCopyDataStruct));
这句代码分配内存的时候,具体是多大是一个限额吧。怎么样能自动根据我XML的大小来自动分配足够的内存。[StructLayout(LayoutKind.Sequential)]publicstructCopyDataStruct{publicintdwData;//附加参数publicintcbData;//数据大小publicIntPtrlpData;//数据内容}
publicintcbData;//数据大小这句代码的作用又是什么?
解决方案:
帐号:zswang昵称:伴水清洁工看帖要回贴“少量数据”?WM_COPYDATA至少可以传递百兆以上的数据-----------------------------------------------设置长度(参考):CopyDataStruct.cbData=[xml].ToString().Length+1;
解决方案:
Windows的消息机制可不是我设计的最好自己到MSDN去查一下WM_COPYDATA相关资料如果XML.ToString()后处理效果还行,那就凑合用。先实际动手做一下看看效果再说。别凭空猜测效率。为提高效率可以考虑采用内存镜像文件,查CreateFileMapping的资料。----------------对于一个指针数据来说它又没有结束标记的。(CC++中的char*至少还有0结束标记,可以不指定大小)没有结束标记的数据块,除了指定其大小你还有什么更好的办法访问它?cbData就是指lpData的大小。-_-!!!
解决方案:
消息是不错的选择或者用socket,以后扩展网络也可以
解决方案:
zswang的copy_data在本机进程间通讯是个很好的选择.包括大量数据.进程通讯有很多种,单机的网络的,有些只适用与单机,有些两者同时适用.这方面我们可以参考微软的sqlserver的进程通讯机制,本机采用的是共享内存(共享内存区和copy_data实质一样的),网络上采用的是socket和namedpipe,想来这样的效率比较好.
解决方案:
学习,受益ing
解决方案:
怎么样能做到传送大量数据啊。
解决方案:
up
解决方案:
哪位大侠指条明路
解决方案:
留名!待用到时再看!
解决方案:
好
解决方案:
用命名管道吧~LZ去参考一下MSDN..net下不知道有没有相对应的类.
解决方案:
弱弱的问可不可以收藏这里的代码?
解决方案:
Mark
解决方案:
继续期待高手....
解决方案:
这么长时间了。有高手指点一下吗?