C# 通过WPF中的wndProc与另一个进程(相同的源代码)通信

C# 通过WPF中的wndProc与另一个进程(相同的源代码)通信,c#,wpf,windows,C#,Wpf,Windows,我正在通过WPF中的HwndSource实现与另一个进程的通信 我希望我的程序(我们称之为A)与windows上另一进程上的程序(也叫A)通信。 下面的图片将帮助我解释我一直在做什么以及我想要实现什么 两个窗口是完全相同的程序(只是背景颜色不同),它们确切地知道各自的句柄。若我注意到两个进程有相同的标题,那个么我调用sendMessage,它是在user32.dll中定义的,带有Message-Raw-input-Message常量,可以全局泵送消息-0x0100WM\u KEYDOWN //

我正在通过WPF中的
HwndSource
实现与另一个进程的通信

我希望我的程序(我们称之为
A
)与windows上另一进程上的程序(也叫
A
)通信。
下面的图片将帮助我解释我一直在做什么以及我想要实现什么

两个窗口是完全相同的程序(只是背景颜色不同),它们确切地知道各自的句柄。若我注意到两个进程有相同的标题,那个么我调用
sendMessage
,它是在
user32.dll
中定义的,带有Message-Raw-input-Message常量,可以全局泵送消息-
0x0100
WM\u KEYDOWN

//如果程序相同,但进程不同
IntPtr lpData=Marshal.StringToHGlobalAnsi(“Hi,Im发送方”);
Show(Marshal.PtrToStringAnsi(lpData));
DisplayAnotherProcessHandle.Text=p.MainWindowHandle.ToString();
SendMessage(p.MainWindowHandle,WM_RawInput_键,IntPtr.Zero,lpData);
我成功地将
WM\u RawInput\u键
IntPtr.Zero
传递给对手程序。但是我对lParam有问题。我无法获取LPRAM数据。我试图用
封送.StringToBSTR
封送.StringToAuto
封送
c#string
。。。但在下面的方法中,我只得到
Empty.String

private IntPtr WndProc(IntPtr hwnd、int msg、IntPtr wParam、IntPtr lParam、ref bool handled)
{
如果(msg!=WM_RawInput_key)返回IntPtr.Zero;
if(wParam==IntPtr.Zero)//1)
{
Show(“已经存在2个进程”);
返回;
}
var path=(System.Reflection.Assembly.GetExecutionGassembly().GetName().CodeBase);
过程p=新过程();
p、 StartInfo.FileName=路径;
p、 Start();
}
私有无效发送消息\u单击(对象发送方,路由目标)
{
foreach(var p in Process.getProcessByName(AppName))
{
如果(p.MainWindowHandle==Process.GetCurrentProcess().MainWindowHandle)继续;
{
IntPtr lpData=Marshal.StringToHGlobalAnsi(“Hi,Im发送方”);
Show(Marshal.PtrToStringAnsi(lpData));
DisplayAnotherProcessHandle.Text=p.MainWindowHandle.ToString();
SendMessage(p.MainWindowHandle,WM_RawInput_键,IntPtr.Zero,lpData);
}
}
}
私有void AddHandler\u单击(对象发送方,路由目标)
{
HwndSource=HwndSource.FromHwnd(Process.GetCurrentProcess().MainWindowHandle);
AddHook(新的HwndSourceHook(WndProc));
}
}

wparam和LPRAM只是指向本地进程内存的指针,其他进程无法访问。
wparam
在您的示例中运行良好,因为您只处理指针值,而不是它所指向的数据

出于类似的目的,我使用了message,其中提供了指向。在那里,您还可以封装复杂的数据结构,这些结构可以在接收过程中以只读方式处理

Microsoft在此提供了一个有用的示例:
谢谢你,Mihaeru,实际上我是在发布我的问题后,在Wpf中用
WM_COPYDATA
查找
sendMessage/wndProc
的示例源代码的。与原始输入消息一样,
WM_KEYDOWN
WM_COPYDATA
也提供全局消息泵(对吗?),我不知道旧窗口的确切理论…-)

我失败了很多次。我发现我应该用字符串长度分配
cbData
。如果我添加属性
[marshallas(UnmanagedType.LpWStr)]
每个字符包含2个字节,那么我需要将
字符串.length*2
分配给cbData

我成功地将消息传递给对手进程

以下来源是答案来源

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
公共结构COPYDATASTRUCT
{
公共IntPtr数据;
公共数据;
[Marshallas(UnmanagedType.LPStr)]
公共字符串数据;
}
[DllImport(“user32.dll”)]
私有静态外部布尔发送消息(IntPtr hWnd、UInt32 Msg、IntPtr wParam、ref COPYDATASSTRUCT lParam);
字符串AppName;
公共静态UInt32 WM_COPYDATA=0x004A;
公共主窗口()
{
初始化组件();
AppName=this.Title;
}
专用IntPtr WndProc(IntPtr hwnd、int msg、IntPtr wParam、IntPtr lParam、ref bool HANDED)
{
如果(msg!=WM_COPYDATA)返回IntPtr.Zero;
if(wParam==IntPtr.Zero)
{
COPYDATASTRUCT cd=新的COPYDATASTRUCT();
cd=(COPYDATASTRUCT)Marshal.PtrToStructure(lParam,typeof(COPYDATASTRUCT));
MessageBox.Show(cd.lpData);
display succeedornot.Text=cd.lpData;
}
返回IntPtr.Zero;
}
private void CreateNewProcess_单击(对象发送方,RoutedEventTarget e)
{
if(Process.getProcessByName(AppName).Length>1)
{
Show(“已经存在2个进程”);
返回;
}
var path=(System.Reflection.Assembly.GetExecutionGassembly().GetName().CodeBase);
过程p=新过程();
p、 StartInfo.FileName=路径;
p、 Start();
}
私有无效发送消息\u单击(对象发送方,路由目标)
{
foreach(var p in Process.getProcessByName(AppName))
{
如果(p.MainWindowHandle==Process.GetCurrentProcess().MainWindowHandle)继续;
{
IntPtr lpData=Marshal.StringToHGlobalAnsi(“Hi,Im发送方”);
COPYDATASTRUCT cd=新的COPYDAT