Passing a string from one instance of C# app to another using PostMessage

R

Rune Jacobsen

Hi all,

I am working on my single instance application that now also has a URL
type associated with it, according to the Asynchronous Pluggable
Protocols information from MSDN. Now, if my application is not already
started, everything works fine. The APP setup starts my program with the
URL as the command line argument, and it displays the proper information
to the user. This works great and was a pleasure to program.

However, my challenge comes when the application is already running.
Thanks to some tips from Nicholas Paldino here on the group, I
originally handled this by using RegisterWindowMessage to obtain a
unique msg id, then I PostMessage'd it to HWND_BROADCAST in order to
tell the existing instance to show itself. Then the second instance
would simply exit.

Now, however, Windows is starting a second instance along these lines;

"C:\Program Files\MyApp\MyApp.exe" "MyProtocol://Heyheyhey/gunk"

What I need is for the second instance of the application to pass
"MyProtocol://Heyheyhey/gunk" to the existing instance before it dies.
My first idea was simply to do another RegisterWindowMessage and pass
the string as one of the parameters, but it seems after intense googling
that it's not going to be that easy.

What would you guys say is The Right Way to do something like this? My
application is in C# with VS 2003 and .Net 1.1. If possible, I would
like to make this as simple as I can, but I realize I might have to give
up that comfort to get something that actually works. :)

Any advice will be accepted with gratitude!

Keep up the good work!

Rune
 
W

Wiktor Zychla [C# MVP]

Now, however, Windows is starting a second instance along these lines;
"C:\Program Files\MyApp\MyApp.exe" "MyProtocol://Heyheyhey/gunk"

What I need is for the second instance of the application to pass
"MyProtocol://Heyheyhey/gunk" to the existing instance before it dies. My
first idea was simply to do another RegisterWindowMessage and pass the
string as one of the parameters, but it seems after intense googling that
it's not going to be that easy.

What would you guys say is The Right Way to do something like this? My
application is in C# with VS 2003 and .Net 1.1. If possible, I would like
to make this as simple as I can, but I realize I might have to give up
that comfort to get something that actually works. :)

yes, indeed, this is not as easy as it looks like because the memory is
addressed virtually (the same virtual address in two separate processes
points to different place in physical memory).
however, since you do know how to pass messages between instances, one of
the simplest solutions (altough not very efficient with really long
messages) would be to pass the string char-by-char since passing integer
values IS easy (you just pass the integer value as one of the message
parameters). the actual code would be then:

// pass consecutive letters
foreach ( letter c in string_to_pass )
PostMessage( where, whatmessage, c, 0 );
// indicate the end of the string
PostMessage( where, whatmessage, 0, 0 );

there are of course also other possibilities that for example involve
allocating/freeing global memory but I do not think you need anything like
that for your simple task.

Regards,
Wiktor Zychla
 
M

Matt

Wiktor said:
yes, indeed, this is not as easy as it looks like because the memory is
addressed virtually (the same virtual address in two separate processes
points to different place in physical memory).
however, since you do know how to pass messages between instances, one of
the simplest solutions (altough not very efficient with really long
messages) would be to pass the string char-by-char since passing integer
values IS easy (you just pass the integer value as one of the message
parameters). the actual code would be then:

// pass consecutive letters
foreach ( letter c in string_to_pass )
PostMessage( where, whatmessage, c, 0 );
// indicate the end of the string
PostMessage( where, whatmessage, 0, 0 );

there are of course also other possibilities that for example involve
allocating/freeing global memory but I do not think you need anything like
that for your simple task.

Ack. I can't imagine doing something like that :)

The two easy possibilities (easy being relative in Windows) are:

1) A named pipe
2) Create a private data type on the clipboard and send a message
indicating it is there.

Oh, you could also just write it to a file :)

Matt
 
C

Colin Neller

Rune,
What would you guys say is The Right Way to do something like this? My
application is in C# with VS 2003 and .Net 1.1. If possible, I would like
to make this as simple as I can, but I realize I might have to give up
that comfort to get something that actually works. :)

See
http://www.vbaccelerator.com/home/N...Simple_Interprocess_Communication/article.asp
for an example of using WM_COPYDATA to communicate between processes. I am
currently using this technique in production code and it works like a charm.
 

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