C# win32 API PostMessage在2个进程间能发送字符串吗?

宏尘 2012-08-14 06:00:24
一个进程间互相通信的问题:PostMessage字符串的传递

代码如下,
发送方(a.exe):
[DllImport("user32.dll",CharSet=CharSet.Auto )]
public static extern int PostMessage(int hwnd, int msg, int wparam, StringBuilder lParam);


PostMessage(345818381, 0x77, 0,new StringBuilder("abcdefg"));


接收方(b.exe):
protected override void DefWndProc(ref System.Windows.Forms.Message m){
switch (m.Msg){
case 0x77:
String info = Marshal.PtrToStringAuto(m.LParam);
break;
}
}
问题,info的结果为空""值,而不是"abcdefg";网上有传说,消息被处理被,"abcefg"的内存已被释放,请问各大侠是怎么回事咯,该怎么传递才能成功传递字符串?
网上苦寻结果,大多是复制来复制去的文章,无具体完整的实例,只好在这里寻求帮助了。
(注:请不要让我改用SendMessae,这里我用PostMessage(或其它发送完消息立即返回的api)会更好一点),谢谢!
...全文
627 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
宏尘 2012-09-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

我是用下面的方法取得的。
仅供参考
C# code

protected override void DefWndProc(ref Message m)
{
string resut;
switch (m.Msg)
{
case WM_COPYDATA:
r……
[/Quote]
#13楼解译了这个方法形不通,除非用SendMessage来发送COPYDATA,这没问题。但我指的是用PostMessage来发送
535cheng110 2012-09-03
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 10 楼 的回复:

我是用下面的方法取得的。
仅供参考
C# code

protected override void DefWndProc(ref Message m)
{
string resut;
switch (m.Msg)
{
case WM_COPYDATA:
r……

你那是在同一个进程里父子关系的窗体之间POSTMessage的吧?
我指……
[/Quote]

是两个独立的进程,a.exe发送,b.exe接受。
我们那个项目为了确保b.exe能够接受到,在a发送消息之前还要检测b是否启动。
不知道你为什么取不到消息,是不是发送有问题?
lizhibin11 2012-09-02
  • 打赏
  • 举报
回复
因为PostMessage只是将消息放入对方的消息队列,在对方进程读取到字符串之前也要注意GC会移动字符串的内存,所以应该用Marshal.AllocHGlobal或者Marshal.AllocCoTaskMem为字符串分配空间,对方进程在读取完毕之后最好回发一个消息,发送方收到消息后释放内存。
lizhibin11 2012-09-02
  • 打赏
  • 举报
回复
如果用PostMessage,就不能用WM_COPYDATA,msg应该用另外的大于0x0400小于0xffff的自定义数值,并且无法在消息处理中直接读取另一个进程的字符串内容,只能从wParam或者lParam中先得到字符串地址,然后用ReadProcessMemory读取字符串。
宏尘 2012-09-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

我是用下面的方法取得的。
仅供参考
C# code

protected override void DefWndProc(ref Message m)
{
string resut;
switch (m.Msg)
{
case WM_COPYDATA:
r……
[/Quote]
你那是在同一个进程里父子关系的窗体之间POSTMessage的吧?
我指的是2个独立的进程a.exe 和b.exe之间互相通信。
b.exe里获取从a.exe里PostMessage过来的WM_COPYDATA咯
superliu1122 2012-08-31
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
同问同问,我也在找PostMessage发string,我也是接收端接收的时候转换为string时,总是空的。
我用SendMessage发WM_COPYDATA成功的,WM_COPYDATA只能用SendMessage发,不能用PostMessage的。,但是现在要用PostMessage,不知道该怎么办了。
[/Quote]
因为PostMessage发送的只是字符串的起始地址,由于两个进程的内存空间是相互独立的,近程B按照接收到的地址去获取字符串内容,当然得不到正确的内容
535cheng110 2012-08-31
  • 打赏
  • 举报
回复
我是用下面的方法取得的。
仅供参考

protected override void DefWndProc(ref Message m)
{
string resut;
switch (m.Msg)
{
case WM_COPYDATA:
resut=GetStringByMsg(m);
..............
}
..............
}
private string GetStringByMsg(Message msg)
{
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT)msg.GetLParam(mytype);
return mystr.lpData;
}
宏尘 2012-08-31
  • 打赏
  • 举报
回复
自已给自已顶一下,期待高人解救。
紫舞玥汐 2012-08-28
  • 打赏
  • 举报
回复
同问同问,我也在找PostMessage发string,我也是接收端接收的时候转换为string时,总是空的。
我用SendMessage发WM_COPYDATA成功的,WM_COPYDATA只能用SendMessage发,不能用PostMessage的。,但是现在要用PostMessage,不知道该怎么办了。
宏尘 2012-08-14
  • 打赏
  • 举报
回复
我知道。是WM_COPYDATA,呵呵。
SocketUpEx 2012-08-14
  • 打赏
  • 举报
回复
是WM_COPYDATA啊
我错了你也跟着错


宏尘 2012-08-14
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

很久没试过了
但根据我的经验
WM_COPDATA肯定可以
[/Quote]
SendMessage用WM_COPDATA的话可以。基本上百度了个底朝天,但还没哪个PostMessage用WM_COPDATA成功过
(我是指2个独立的应用程序的进程,不是同一个进程之内的2个窗体之间哦),连PostMessage用String都没有成功过。
宏尘 2012-08-14
  • 打赏
  • 举报
回复
网上大多是复制性的东东,没实质性的解答,有些解答也都只有一半,有发送方的代码,没有接收方的代码。百度我搜一天了都没搜到用字符成功传递的结果。有一种方法用共熟内存的方式,但我不就是想传递一个字符串吗?把共享内存都搬出来了,太复杂化了。c#不至于这么水吧。^-^
SocketUpEx 2012-08-14
  • 打赏
  • 举报
回复
很久没试过了
但根据我的经验
WM_COPDATA肯定可以


宏尘 2012-08-14
  • 打赏
  • 举报
回复
你试过用WM_COPDATA传递不?成功了不?成功的麻请给我发段(发送方和接收方的)代码出来咯,因为我试过这种方法,但同样不成功。
所以才采用比较简单一点的字符串来传递,没想也不成功。SendMessage倒是用WM_COPDATA可以。
SocketUpEx 2012-08-14
  • 打赏
  • 举报
回复
用WM_COPDATA


110,525

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧