Communication between programs?

BlitzMax Forums/BlitzMax Programming/Communication between programs?

xlsior(Posted 2007) [#1]
I'm currently writing an application that needs to be associated with a particular file extension -- but more importantly, I only want a single copy of the program running to deal with multiple files.

Is there an 'easy' way to handle this?

I know how to check the list of running processes upon application launch so the app can find out if there is already another copy running -- but how can one pass the name of the file to the already running application and trigger it into opening the file instead?

Or is the above going at it all wrong?


Gabriel(Posted 2007) [#2]
You want CreateMutex from Kernel32. Lots of documentation about it on the MSDN, of course, but something like this :

Extern "Win32" 
   Function GetLastError:Int() = "GetLastError"
   Function CreateMutex:Int(lpMutexAttributes:Int,bInitialOwner:Int,lpName$z)
End Extern

Const ERROR_ALREADY_EXISTS:Int=183

CreateMutex(0,1,"My Program Instance")

If GetLastError() = ERROR_ALREADY_EXISTS Then
	' PROGRAM IS ALREADY RUNNING - SHUTDOWN
Else
	' PROGRAM IS NOT RUNNING, GO AHEAD
EndIf


That's off the top of my head, so it might not be 100 percent.

EDIT: You may have to make some minor modifications to get the CreateMutex function to link properly, but the site won't let me post them. Sorry about that.


Gabriel(Posted 2007) [#3]
I have no idea why the code I posted above is being censored by the security measures. Perhaps someone from BRL can tell me why.

As I said, you need CreateMutex, but since apparently any code sample sends the site censor into a fit, you should probably check the MSDN for an explanation.


xlsior(Posted 2007) [#4]
Thanks, but that only deals with the program detecting whether it is the first instance or if another one already exists -- I could do that already (although the code above is definitely a lot cleaner than mine was, so thanks for that!)

The real question is how the 2nd instance can pass on its parameters to the 1st instance, so it can handle the file(s) I'm trying to open. Is there some way to trigger an event in the 1st program that passes the info along?


Gabriel(Posted 2007) [#5]
Oh sorry, I got so caught up in the forum messing with my code that I clean forgot the second part. Just grab the process ( as I guess you already are ) and send it a message with SendMessage ( also in the WinAPI.)

I believe the correct message to send is WM_COPYDATA.

I can't find anything directly in BMax, but perhaps this page explains it well enough for you.

http://www.codeguru.com/cpp/w-p/system/processesmodules/article.php/c5777/

Worst case, you could always open up a socket and send data that way, but I think WM_COPYDATA is probably the clean, recommended way to do it.


xlsior(Posted 2007) [#6]
I found another thread with some further info that is somewhat related to this: http://www.blitzbasic.com/Community/posts.php?topic=48863

That one sends text to an edit field in another program. Not exactly what I'm after, but it might provide a start...

(It does appear that the forum is messing with lines containing the @ symbol, so it needs a little tweaking to work.)


xlsior(Posted 2007) [#7]
Ok, I ended up going with Budman's shared memory routine , which so far appears to work great.

Thanks for the pointers Gabriel, but I just couldn't get it to work. :-?


SebHoll(Posted 2007) [#8]
I'm not sure that that is the proper way to get this behaviour, although if you're happy it works, nevermind.

The Windows shell uses DDE to communicate with currently running instances of your program when you open a file in Explorer and if you can interpret and respond to these message positively, then it will not open another instance.

If you have a look at the File Type properties for commercial applications (like MS Office), they all have DDE setup so that they can acheive the effect your after. The idea is you can tell the shell to send the file path to your application instance using DDE and you can open it internally. However, I haven't tried doing this in Blitz so I can't give you much more info than that. Maybe someone who actually knows what there doing with the Windows API could help with trying to implement this - I'd be interested in getting this working too.

Edit: Here's an MSDN page on using DDE and a diagram taken from that page showing data flow:



I can't make much sense out of it though. :-(


TartanTangerine (was Indiepath)(Posted 2007) [#9]
http://www.codeproject.com/cpp/avoidmultinstance.asp - this is all you need - shared memory is overkill