方案1、使用WM_COPYDATA消息
方案2、使用WriteProcessMemory(),ReadProcessMemory()访问其他进程的内存
方案3、使用内存镜像文件

解决方案 »

  1.   

    来源程序
    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);
            }
        }
    }
      

  2.   

    顺便问问...少量数据时用WM_COPYDATA消息处理的确很方便...但是发送的数据类型很有限, 貌似只能发送String、Char等等. 以前尝试过想将整个Object发送, 但是最终失败收场...请问zswang有没有办法把Object对象发送到目标进程窗口???前提, 两个程序都引用了这个Object类型的...^o^
      

  3.   

    “少量数据”?WM_COPYDATA至少可以传递百兆以上的数据
    “只能发送String、Char等等”?WM_COPYDATA传递的是一个缓冲区,照你这样说内存里只能存放String、Char等等了。
    object不是单纯的数据类型,它和类及其继承类都有关系。
    内存地址都是相对于自身进程的,除非自己写个操作系统用物理地址得了。
      

  4.   

    呵呵...那么Object只能先序列化再传递吗???^o^
      

  5.   

    传送Object对象的时候就会出现问题。
    [StructLayout(LayoutKind.Sequential)]
            public struct CopyDataStruct
            {
               public int dwData; // 附加参数
                public object data; //传送的数据
                public int cbData; // 数据大小
                public IntPtr lpData; // 数据内容       <--比这个大
            }
    这样写这个CopyDataStruct 类,程序就会出错。何解???请指教!
      

  6.   

    如果加上的话。异常信息如下:未处理 System.Runtime.InteropServices.COMException    
    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()  
      

  7.   

    “少量数据”?WM_COPYDATA至少可以传递百兆以上的数据 
    “只能发送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; // 数据大小
    这句代码的作用又是什么?
      

  8.   

    帐号:zswang
    昵称:伴水   清洁工   看帖要回贴“少量数据”?WM_COPYDATA至少可以传递百兆以上的数据 
    -----------------------------------------------设置长度(参考):CopyDataStruct.cbData = [xml].ToString().Length + 1;
      

  9.   

    Windows的消息机制可不是我设计的
    最好自己到MSDN去查一下WM_COPYDATA相关资料如果XML.ToString()后处理效果还行,那就凑合用。
    先实际动手做一下看看效果再说。别凭空猜测效率。为提高效率可以考虑采用内存镜像文件,查CreateFileMapping的资料。
    ----------------
    对于一个指针数据来说它又没有结束标记的。(C\C++中的char*至少还有0结束标记,可以不指定大小)
    没有结束标记的数据块,除了指定其大小你还有什么更好的办法访问它?
    cbData就是指lpData的大小。
    -_-!!!
      

  10.   

    消息是不错的选择或者用socket,以后扩展网络也可以
      

  11.   

    zswang 的copy_data在本机进程间通讯是个很好的选择.包括大量数据.
    进程通讯有很多种,单机的网络的,有些只适用与单机,有些两者同时适用.这方面我们可以参考 微软的 sql server 的进程通讯机制,本机采用的是 共享内存(共享内存区和copy_data实质一样的),网络上采用的是 socket 和 named pipe,想来这样的效率比较好.
      

  12.   

    用命名管道吧~
    LZ去参考一下MSDN.
    .net下不知道有没有相对应的类.