2010-01-15 262 views
0

我试图让2应用程序使用windows消息相互通信。但是,我在分配内存和编组数据期间一直在获取AccessViolationException(试图读取或写入受保护的内存)。通过win消息在应用程序之间进行通信

有人可以向我解释什么是错的或建议更好的方法吗? 谢谢。

编辑:使用WM_COPYDATA建议,但现在我有另一个问题 - 其他应用程序没有收到WM_COPYDATA消息。怎么了?发送味精

代码:用于接收MSG(在其他应用程序)

public const int WM_COPYDATA = 0x004A; 
public struct COPYDATASTRUCT 
{ 
    public int dwData; 
    public int cbData; 
    public DATA lpData; 
} 

public struct DATA 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=50)] 
    public char[] msg1; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=50)] 
    public char[] msg2; 
} 

[DllImport("User32.dll")] 
public static extern int SendMessage(int hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); 

private void button1_Click(object sender, EventArgs e) 
{ 
    // data, with null terminated strings 
    COPYDATASTRUCT cds = new COPYDATASTRUCT(); 
    cds.lpData.msg1 = textBox2.Text.PadRight(50, '\0').ToCharArray(); 
    cds.lpData.msg2 = textBox3.Text.PadRight(50, '\0').ToCharArray(); 
    cds.cbData = Marshal.SizeOf(cds.lpData); 
    int result = SendMessage(hwnd, WM_COPYDATA, System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, ref cds); // winAPI 

} 

代码:

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == WM_COPYDATA) 
    { 
     // doesn't get into this part 

     COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); 
     .... 
    } 
    base.WndProc(ref m); 
} 
+0

除了'Convert.ToChar(0x0)',你可以编写'“\ 0”'。 – SLaks 2010-01-15 03:56:36

+0

在切换到“WM_COPYDATA”之前,其他应用程序是否收到消息? – SLaks 2010-01-15 14:23:54

回答

2

Windows(和其他现代操作系统)中的指针是与进程相关的。您正在发送指向源进程虚拟内存中地址的指针。在目标进程中,这个相同的虚拟内存位置可能不会被映射,如果它被映射,它将会完全不同。

进程之间复制数据,使用WM_COPYDATA消息和Windows操作系统COPYDATASTRUCT。操作系统提供了这些特殊处理:它在进程之间复制引用数据,并为目标进程提供一个指向目标进程内存空间中复制数据的指针。

另外,您的Marshal.StructureToPtr调用看起来不正确。你的结构体包含两个指针(因为char []是一个引用类型),所以你要将两个指针复制到你的HGLOBAL中,而不是字节数组的内容。您可能能够使用MarshalAsAttribute(UnmanagedType.ByValArray)来解决这个问题,但在这种情况下您需要添加大小信息。更简单的解决方案可能是使用Marshal.Copy方法将数组复制到非托管内存中。

最后,如果您可以控制应用程序,并且可以使用.NET 3.0或以上,考虑托管WCF服务和发送数据的方式。您可能会发现比使用Windows消息更容易,因为它会为您处理数据的序列化和反序列化 - 但我意识到这可能不适合您,或者您可能已经排除了它。

+0

我使用的是2.0框架,所以WCF不适合我。 – ahbird 2010-01-15 08:00:45

0

回答您编辑的问题:

您确定您拥有正确的HWND吗?

用狙++,以确保该HWND是正确的,并检查间谍++是否看见这条消息。

确保您在这两个应用正确定义WM_COPYDATA不变。

相关问题