tags:

views:

1037

answers:

5

I need to start 1-3 external programs in my Java application that have paths defined by the user. I have few requirements:

1) I don't want the program to execute if it is already running

2) I don't want any of the programs to steal focus from my Java application

3) I don't care if any of them fail to start or not...they just need to fail silently.

Here is what I have come up with so far:

ProcessBuilder pb = new ProcessBuilder(userDefinedPath1);
try {
    pb.start();
}
catch (Exception e) {
    // Something went wrong, just ignore
}

And then I obviously just repeat that 3 more times with the other two paths. This starts like I would expect and meets my third requirement just fine, but fails on the first two.

Can I make this work as I want it to? Thanks in advance.

Edit:

Thanks for the advice so far. Some points of clarification:

1) I don't have any control of these other apps. They are third party. Also, they could have been start or stopped by the user manually at any time.

2) I know the EXACT names of the executables (e.g. "blah.exe") and they will ALWAYS be the same, but the paths to the executables won't necessarily be.

3) Batch file wrappers are not feasible here.

4) The other apps are NOT java apps, just plain old Windows executables.

Does that change anything?

Also, of the two points that I'm trying to solve, the second one is more important. The applications I'm running seem to detect if another one of itself starts and close the duplicate, but it creates a bad user experience (brings up splash screen, flashes on the taskbar, etc). The focus issue is much more important to solve.

+1  A: 

I'm guessing you don't have control over the other two apps... If you did, this wouldn't be too bad--you could just have them listen to a socket and see if the socket is available when you come up.

The next solution may actually be language independent. You could manage the whole system through batch file wrappers. Write a batch file that creates a file when it starts up and deletes it when it stops. Unix systems use this technique a lot--they call the file a lock file more often than not.

If only your app will ever start these other apps, then you could simply track if you've started it or not, so I'm guessing this isn't possible or you wouldn't be asking, so I'm assuming that the user may have launched these programs through some other mechanism.

If you have NO control over the launching of the other apps and can't even write a batch file to launch them, then you just can't do what you want to do (Note, the apps would have to always use the batch file, even if the user started them by hand).

I just a very-last ditch effort might be to get a process status and parse it, but you'd have to know exactly what the other apps were called in the PS, this isn't really trivial. Also, all java apps tend to have the same exact signature in most process status printouts which could make this useless.

The problem is that if one of these programs were started outside your app, you have virtually NO WAY to identify that fact unless you happen to know it's exact process status signature, and even then it's flaky.

Bill K
I'm going to accept this as the solution because it pretty much sums it up...there are nothing more than flaky round about ways to do this with no proper solution.
Morinar
+1  A: 

If I were dealing with this problem on a unix based system I would be tempted to write a native function to gather process information and attempt to launch the external applications. This goes against the spirit of Java, but the type of information you are trying to gather and the control of application launch are outside of the JVM.

I do not know enough about Windows programming to point you in the right direction, but I imagine there are Windows API calls you could access in .NET languages or plain C++ that could help you with your second criterion. Perhaps you could change the question to attract the non-Java developers who could help.


Edit:

Check out the Shell Execute Function of the Windows API. The SW_SHOWNOACTIVATE option appears to allow the current window to remain active.

Daniel Nesbitt
+1  A: 

See Check if a program or process is running (Windows)

This tip will detect if a given program is running. Ok, it's not pretty because of the vbscript but it's easy to implement.

RealHowTo
A: 

on windows xp (pro?) you can launch the command 'tasklist' and parse the output to determine if a process is running. you can use threads for avoiding any problem with focus (i think)

Adrian Pascalin
A: 

You can use jps to know the running java program status. jps is one the java tool like javac, java etc.,