Solved

Determining if a Java Application is already running

Posted on 1999-01-26
5
1,154 Views
Last Modified: 2013-11-23
Lots of applications I've written in C++ start out by checking to see if there's already an instance of the application running, and if so, bringing that instance's main window to the foreground, at which point, the second instance exits.

I want to have similar functionality in my Java Application (stand-alone app, not applet).

First, is there a pure-Java way to achieve this effect?
If not, I will increase the value of this question to 200 points if you have a good JNI native implementation.

One thought I had was to try and get a Process object for the current JavaVM process and store that as a desktopProperty on the default Toolkit. However, you can only get Process objects from the Runtime for sub-processes that you spawn via exec(). And, you can't call Toolkit.setDesktopProperty() because it's protected.

Thanks for your help. If your native code solution works, I'll increase the value of this question before I grade it.

bre++
0
Comment
Question by:circuit
  • 2
  • 2
5 Comments
 
LVL 8

Expert Comment

by:diakov
Comment Utility
Let me elaborate.
I assume Win platform.

1. (pureJava solution) When you start your app, you can put a listening socket on a port on the local host. The next instance will first connect to this port to chech whether it has been started yet, and will exit if already running. Bringing the first instance to front, might be possible, the second program can tell the first one ot go to front through the socket, but I don't know how to do that pure java (bringing an Java app to the front), perhaps window1.toFront() on the main window will achieve this.

2. (JNI solution) Using the Win API, it is very easy to enumerate all windows, get their captions, check them and bring to focus. I have this code ready, it just have to be incorporated by the JNI and validated against Java windows.

3. You can use other flags, like temporary files in a temp directory, phrases in ini files, etc, etc, to mark the running application, so a second instance can find about it. This however constrains to second instance detection.

Hopoe this helps,
  Nik

0
 
LVL 1

Expert Comment

by:mrgentry
Comment Utility
In a Win32 environment I believe the easiest (and apparently standard) way to tell if an application is already running is to have the application create a mutex (use some unique name for the mutex) and check for a return error of ERROR_ALREADY_EXISTS.

// Let's make sure only one copy of this executable can run at once.
HANDLE hMutex = CreateMutex(NULL, FALSE, "MyApp instance mutex");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
       CloseHandle(hMutex);
       exit 1;
}

I think you'd probably have to use diakov's suggestion regarding finding the first instance's main window in order to bring it to the foreground.

Seems to me that diakov's suggestion for a pure java solution would work reasonable well, though I think you'll find that on some Windows machines you'll find that your application will cause dial-up networking to start.  I can't think of anything off the top of my head anyway that might be a better way to do it.

I wouldn't suggest using a temporary file to indicate the application is already running since if it ever fails to delete this file it would have to be removed manually to allow the application to run even a single instance again.

0
 

Author Comment

by:circuit
Comment Utility
Nik, please just send a blank answer to this question and I'll give you the 100 points. I figured out my own native implementation.

Thanks again,
bre++
0
 
LVL 8

Accepted Solution

by:
diakov earned 100 total points
Comment Utility
Thanx. Just in case, a small fragment of C++ code:
///-----------------
typedef struct
{
      BOOL found;
      HWND hwnd;
} EnumStruct;

BOOL CALLBACK EnumWindowsProc(
    HWND hwnd,      // handle to parent window
    LPARAM lParam       // application-defined value
   )
{
      char Title[100];
      EnumStruct *p = (EnumStruct *)lParam;

      if (hwnd != NULL)
            GetWindowText(hwnd, Title, 100);
      else
            return FALSE;
      if (strcmp(Title, STUB_NAME) == 0) //stub name is the //name of the window you're looking for.
      {
            p->hwnd = hwnd;
            p->found = TRUE;
            return FALSE;
      }
      return TRUE;
}

//Then in the initInstance
BOOL CStubApp::InitInstance()
{
      EnumStruct s;

      s.found = FALSE;
      s.hwnd = NULL;

      EnumWindows(EnumWindowsProc, (LPARAM)&s);
      if (s.found)
      {
            SetForegroundWindow(s.hwnd);
            return FALSE;
      }
//--------------
//...normall initialization and implementation.
}


<lock>
0
 

Author Comment

by:circuit
Comment Utility
Thanks, here's my JNI implementation:


/*   CheckAppRunningImpl.cpp */

#include <jni.h>
#include "CheckAppRunning.h"
#include <stdio.h>
#include <windows.h>

JNIEXPORT jboolean JNICALL Java_CheckAppRunning_bringWindowToFront
  (JNIEnv *env, jobject obj, jstring windowName)
{
      HWND windowHandle;
      const char *str = env->GetStringUTFChars(windowName, JNI_FALSE);
      windowHandle = FindWindow ("SunAwtFrame", str);
      if (windowHandle)
      {
            SetForegroundWindow (windowHandle);
      }
      env->ReleaseStringUTFChars(windowName, str);
      if (windowHandle)
      {
            return JNI_TRUE;
      }
      else
      {
            return JNI_FALSE;
      }
}

JNIEXPORT jboolean JNICALL Java_CheckAppRunning_windowExists
 (JNIEnv *env, jobject obj, jstring windowName)
{
      HWND windowHandle;
      const char *str = env->GetStringUTFChars(windowName, JNI_FALSE);
      windowHandle = FindWindow ("SunAwtFrame", str);
      env->ReleaseStringUTFChars(windowName, str);

      if (windowHandle)
      {
            return JNI_TRUE;
      }
      else
      {
            return JNI_FALSE;
      }
}

/*   CheckAppRunning.java */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


class SimplePanel extends JPanel {

    public SimplePanel() {
      JButton button = new JButton("Hello, world");
        button.setMnemonic('h');

      add(button);
    }
}


public class CheckAppRunning {
    static JFrame frame;
    public native boolean windowExists(String windowName);
    public native boolean bringWindowToFront(String windowName);
   
    public static void main (String []args) {
      System.loadLibrary("CheckAppRunning");

      if (new CheckAppRunning().bringWindowToFront ("Check App Running")) {
            System.out.println ("App already running...exiting");
            System.exit(0);
      }
          
      SimplePanel panel = new SimplePanel();
      
      frame = new JFrame("Check App Running");
      frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {System.exit(0);}
      });
      frame.getContentPane().add("Center", panel);
      frame.pack();
      frame.setVisible(true);
    }
}


0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now