I just want to send a string as a message to a .NET program :(

G

growse

Right, I've got a 2 c# programs here. Lets call them A and B. My aim is
to send a simple string from B to A.

A is always running. I've overridden the WndProc method to give me
messages that are sent to it. B is a program that loads, sends a
message and then quits. Let me give you the code to B (bits are missed
out, but I've got the important stuff there):

private const uint WM_USER_SENDTEXT = 0x8001;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr
wParam, ref StringBuilder lParam);
public arghandler(string assemblyname,string[] args)
{
IntPtr hWnd = FindWindow(null, "ProgramA");
if (hWnd!=IntPtr.Zero)
{
StringBuilder sb = new StringBuilder("hi there");
IntPtr res =
SendMessage(hWnd,WM_USER_SENDTEXT,IntPtr.Zero,ref sb);
bool rah = SetForegroundWindow(hWnd);
}
this.Close();
}


So there we go. I send a reference to a stringbuilder that contains the
string that I want to send "hi there".

Here's the relevant bit of A's WndProc:

case WM_USER_SENDTEXT:
StringBuilder sb = new StringBuilder();
try
{
sb =
(StringBuilder)Marshal.PtrToStructure(m.LParam,typeof(StringBuilder));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
MessageBox.Show("Hey! Got a message here
"+sb.ToString());
break;


Now, when I run A in debug mode and run B, I can always catch the code
getting to this case. I step it through, and it throws an exception at
the PtrToStructure line:

_message "The specified structure must be blittable or have
layout information." string


Ok, so some reading about tells me that a stringbuilder is not a
blittable structure. So lets try with an int. I send a ref int and try
to read it as an int (using typeof(int) and everything). This time, the
int I read out is the same as the int value of lParam. So it's reading
itself as an int and not the int object I put in in program B (42,
btw). Ok, so lets send an int and not a ref int.

_message "Object reference not set to an instance of an object."
string

WTF? What the hell is null here? certainly not lParam, that's 1274539
or something. Why can't I send even a simple int from one .NET program
to another?

Anyone got any ideas?

P.S. I had one idea but not been able to test this one out - is there a
danger that B is sending a pointer to the memory for A to get hold of,
but then quitting before A can do anything with it and therefore
de-allocating it's memory making the pointer not valid?
 
J

Jianwei Sun

I am not exactly sure what you are doing, but if I were you, I will use
sockets to send those message. This case, if you want to scale program A
and B on different machines, it will still work.
 
G

growse

A socket is an interesting idea, but in reality, B and A are the same
codebase. B is just another version of A, that knows that A exists and
wants to tell it something before it quits. In this scenario, sockets
would seem a bit of a faff.


Jianwei said:
I am not exactly sure what you are doing, but if I were you, I will use
sockets to send those message. This case, if you want to scale program A
and B on different machines, it will still work.



Right, I've got a 2 c# programs here. Lets call them A and B. My aim is
to send a simple string from B to A.

A is always running. I've overridden the WndProc method to give me
messages that are sent to it. B is a program that loads, sends a
message and then quits. Let me give you the code to B (bits are missed
out, but I've got the important stuff there):

private const uint WM_USER_SENDTEXT = 0x8001;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr
wParam, ref StringBuilder lParam);
public arghandler(string assemblyname,string[] args)
{
IntPtr hWnd = FindWindow(null, "ProgramA");
if (hWnd!=IntPtr.Zero)
{
StringBuilder sb = new StringBuilder("hi there");
IntPtr res =
SendMessage(hWnd,WM_USER_SENDTEXT,IntPtr.Zero,ref sb);
bool rah = SetForegroundWindow(hWnd);
}
this.Close();
}


So there we go. I send a reference to a stringbuilder that contains the
string that I want to send "hi there".

Here's the relevant bit of A's WndProc:

case WM_USER_SENDTEXT:
StringBuilder sb = new StringBuilder();
try
{
sb =
(StringBuilder)Marshal.PtrToStructure(m.LParam,typeof(StringBuilder));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
MessageBox.Show("Hey! Got a message here
"+sb.ToString());
break;


Now, when I run A in debug mode and run B, I can always catch the code
getting to this case. I step it through, and it throws an exception at
the PtrToStructure line:

_message "The specified structure must be blittable or have
layout information." string


Ok, so some reading about tells me that a stringbuilder is not a
blittable structure. So lets try with an int. I send a ref int and try
to read it as an int (using typeof(int) and everything). This time, the
int I read out is the same as the int value of lParam. So it's reading
itself as an int and not the int object I put in in program B (42,
btw). Ok, so lets send an int and not a ref int.

_message "Object reference not set to an instance of an object."
string

WTF? What the hell is null here? certainly not lParam, that's 1274539
or something. Why can't I send even a simple int from one .NET program
to another?

Anyone got any ideas?

P.S. I had one idea but not been able to test this one out - is there a
danger that B is sending a pointer to the memory for A to get hold of,
but then quitting before A can do anything with it and therefore
de-allocating it's memory making the pointer not valid?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top