通过赢取消息在应用程序之间进

时间:2010-01-15 03:54:36

标签: c# winapi

我试图让2个应用程序使用Windows消息相互通信。 但是,在分配内存和数据封送期间,我一直在获取AccessViolationException(尝试读取或写入受保护的内存)。

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

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

发送消息的

代码:

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);
}

3 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

您需要发送WM_COPYDATA消息。

请参阅this thread

答案 2 :(得分:0)

回答您编辑过的问题:

你确定你有合适的HWND吗?

使用Spy ++确保HWND正确,并检查Spy ++是否看到该消息。

确保您已在两个应用中正确定义WM_COPYDATA常量。