Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当提供数据有效负载时,为什么未收到WM_COPYDATA消息?_C#_Winforms_Pinvoke_Windows Messages_Wm Copydata - Fatal编程技术网

C# 当提供数据有效负载时,为什么未收到WM_COPYDATA消息?

C# 当提供数据有效负载时,为什么未收到WM_COPYDATA消息?,c#,winforms,pinvoke,windows-messages,wm-copydata,C#,Winforms,Pinvoke,Windows Messages,Wm Copydata,我使用(丑陋的)WM_COPYDATA消息对进程间数据交换进行了非常著名的设置。这不是我的决定,我必须在遗留应用程序中支持它 const uint WM_COPYDATA = 0x004A; [StructLayout(LayoutKind.Sequential)] struct COPYDATASTRUCT { public uint dwData; public int cbData; public IntPtr lpData; } [DllImport("user32.dl

我使用(丑陋的)
WM_COPYDATA
消息对进程间数据交换进行了非常著名的设置。这不是我的决定,我必须在遗留应用程序中支持它

const uint WM_COPYDATA = 0x004A;

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
  public uint dwData;
  public int cbData;
  public IntPtr lpData;
}

[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hwnd, uint msg, IntPtr wparam, ref COPYDATASTRUCT lparam);
如果我只发送一个普通结构,而不附加额外的数据,它就可以正常工作:

COPYDATASTRUCT container;
container.dwData = 42;
container.cbData = 0;
container.lpData = IntPtr.Zero;
SendMessage(myHwnd, WM_COPYDATA, IntPtr.Zero, ref container);
在接收器端(一个外部WinForms应用程序),我收到了这条消息,可以正确读取
dwData
字段:

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_COPYDATA)
    {
        var container = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
        MessageBox.Show(container.dwData.ToString()); // 42
    }
    base.WndProc(ref m);
}
但是,只要我附加了一些额外的负载,外部应用程序就会停止接收此消息。在receiver window proc中,
m.Msg==WM_COPYDATA
条件始终为
false
,发送方从
SendMessage
调用中获得
0
结果

COPYDATASTRUCT container;
container.dwData = 42;
container.cbData = 4;
container.lpData = Marshal.AllocHGlobal(4);
int result = SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, ref container); // 0
(实际上,这是一个虚拟有效载荷,但与真实有效载荷相同。)

我还尝试手动封送
COPYDATASTRUCT
(使用
marshal.structoptr
),方法是将
SendMessage
的最后一个参数类型更改为
IntPtr
,但不幸的是没有成功(相同的行为)

我试图通过更改
COPYDATASTRUCT
定义来依赖CLR编组:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct COPYDATASTRUCT
{
  public uint dwData;
  public int cbData;

  [MarshalAs(UnmanagedType.LPWStr)]
  public string lpData;
}
你猜怎么着?没有效果


我的设置有什么问题?当有效负载连接到数据结构时,为什么无法接收消息?

结构定义不正确,应该是

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
  public IntPtr dwData; // in C/C++ this is an UINT_PTR, not an UINT
  public int cbData;
  public IntPtr lpData;
}

您对dwData的定义在32位进程(4字节)中与ok匹配,但在64位进程(8字节)中与ok不匹配。由于这是结构中的第一个字段,因此当其定义不正确时,所有下注都将被取消。

结构定义不正确,应该是正确的

[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
  public IntPtr dwData; // in C/C++ this is an UINT_PTR, not an UINT
  public int cbData;
  public IntPtr lpData;
}
您对dwData的定义在32位进程(4字节)中与ok匹配,但在64位进程(8字节)中与ok不匹配。由于这是结构中的第一个字段,因此当其定义不正确时,所有下注都将关闭。

dwData是IntPtr(变量大小32或64),而不是32位值。它可以在32位上工作,但在64位上会失败。lpData必须是IntPtr,而不是字符串。dwData是一个IntPtr(变量大小为32或64),而不是32位的值。它可以在32位上工作,但在64位上会失败。lpData必须是IntPtr,而不是字符串。