Detecting the state of an exec'ed file

Blitz3D Forums/Blitz3D Programming/Detecting the state of an exec'ed file

D4NM4N(Posted 2006) [#1]
One you use fileexec to run a program, is there a way of detecting if its running or not?
Im trying to detect the state of a 'plug-in' exe.
I cant use the clipboard as im using that as a transport for commands.

I guess theres a way of doing it with a userlib, anyone know which one?

prehaps something like:
programisrunning = DetectAppTitle("myapptitle")

returns 1 or 0


VIP3R(Posted 2006) [#2]
If I remember correctly, the following code might not detect non-Blitz exe's, but it's worth a shot.

Userlib decls...
.lib "kernel32.dll"
CreateMutexA%(lpMutexAttributes%,bInitialOwner%,lpName$):"CreateMutexA"
GetLastError%():"GetLastError"


Blitz code...
CreateMutexA(0,1,"myapptitle")
If GetLastError()=183 Then Print "myapptitle is running"



D4NM4N(Posted 2006) [#3]
i tried it but couldnt seem to get any joy. Is apptitle just that, the actual text thats displayed on the windows title bar?

this one looks promising but i dont know how to assign a long pointer to a null terminated string in b3d
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/html/cereffindwindow.asp

It looks like there are other functions as well where i could use the error state to confirm if running, but they all require a handle and ive no idea how to get that.


VIP3R(Posted 2006) [#4]
Yeh, apptitle is the text in the title bar. You could try it with the process name too (blitzcc.exe etc)

To find the window handle try this...

Userlib decls...
.lib "user32.dll"
FindWindowA%(NullString,WindowText$):"FindWindowA"
GetWindowLongA%(hWnd%,nIndex%):"GetWindowLongA"


Blitz code...
Handle=FindWindowA("","myapptitle")
Long=GetWindowLongA(Handle,-16)


As with the previous example, it works ok in BlitzPlus but I'm not sure about Blitz3D.


octothorpe(Posted 2006) [#5]
A more "low tech" solution might involve relying on simple file system semaphores:

Create a blank file, then run your child process. When the child process is finished, have it delete the file. The parent process can simply check for the existance of the file every second or so.


Picklesworth(Posted 2006) [#6]
The full, proper, and very easy solution is handled by a DLL which I wrote:
http://www.blitzbasic.com/toolbox/toolbox.php?tool=151

It currently uses CreateProcess to launch the program. That shouldn't matter much since it sticks to default values, but if you want the C++ source so that you can change it over to ShellExecuteEx, go ahead and email me.

As far as I know, the DLL works with any compiled program in existence. The Grasshopper Plugin System plugin creator tool uses RunProgram to execute 3 different external programs (a resource compiler, ResHacker, and XVI32) while keeping them completely synchronized 100% of the time. Grasshopper 0.4 also uses the DLL to run Notepad and know when it has been closed.


Picklesworth(Posted 2006) [#7]
*Bump*
I would be quite upset if my contribution, which has a 90% chance of solving this problem with a high level of ease and perfection, was not commented on.
It doesn't look like the problem was actually totally solved previously, so... This bump is to aid D-Grafix, who must have missed his thread being added to.


TartanTangerine (was Indiepath)(Posted 2006) [#8]
A common way to see if a thread is still active is to build in some windows messaging.

Send a message to the application via a global message or direct to the window and wait for a response.

Something like :-

Send "Are you Alive"
Respond "Yes I am"

This will also prevent multiple instances of the same application from being run.


JoeRetro(Posted 2006) [#9]
VIP3R gave everyone the proper answer.

Create a mutex to prevent multiple instances of your application from running.

Use FindWindow to detect a titled application that is running...


Picklesworth(Posted 2006) [#10]
Ah, cool.
Thanks VIP3R! I've always wondered how to do mutexes.

Beware, though: Even with mutexes, you may encounter the need to place arbitrary and dangerous delays to avoid timing problems.
Mutexes are excellent for getting an application to ensure that it only has one instance running, though.

The RunProgram DLL, on the other hand, is a safe method to run programs which fixes the problem of arbitrary delays. It starts tracking from the moment that Windows thinks to launch the program and finishes the moment that it ends (Thus, no issues with timing). Also doesn't require any modifications to the app that is being launched, you don't need to know the window name of the launched program (which would not work in many cases... for example, the window for the app you are currently running to read this), the program being launched could take a millisecond to complete without tossing yours into an infinite loop (which is possible with some of the many techniques which I have explored for two of my projects), and the launched program doesn't even need to be in a window!


John:
www.blitzbasic.com/toolbox/toolbox.php?tool=151
(As mentioned above)


John Blackledge(Posted 2006) [#11]
Hi Mr Pick.
What is this RunProgram DLL that you speak of?


Barliesque(Posted 2006) [#12]
@John Blackledge
Click on the link in Mr. Pickles' post above.

Another solution--not that another is needed--is to use the clipboard. D-Grafix mentioned above that he's already using the clipboard to pass messages between other components of his project, and so he couldn't also use it for this purpose. But it *could* be used by multiple processes... If you allow multiple messages to be contained in the clipboard, with a sender/receiver tag for each message. You could append and delete messages to/from a list and thus allow several components to exchange simple messages.


John Blackledge(Posted 2006) [#13]
Nice. Thanks Mr Pick!