Angeline
Angeline

Reputation: 57

How to re-add icon to system tray after explorer.exe crash

My java application currently has an icon in the system tray. When the system tray crashes, however (you can simulate this by killing explorer.exe in the taskbar), the icon disappears after the system tray returns.

When I check SystemTray.getSystemTray().getTrayIcons() for the icons in the system tray, it always shows that my TrayIcon is still in the system tray, even though after it crashes and reloads and my tray icon is longer there.

At the moment I'm removing and adding my icon once every 15 seconds or so, but is there any other way of implementing this so that it won't keep disappearing and appearing and annoying the user?

Upvotes: 4

Views: 986

Answers (3)

Zakir Ayub
Zakir Ayub

Reputation: 105

This is the way I fixed it. This is an extension to the first answer. I go into a bit more detail.

I have a thread running which checks the pid (process ID) of the explorer each 10 seconds. If the process ID changes, a new method is called to dispose the old existing icon that has disappeared and adds a new one.

private volatile boolean isRunning = true;

public void startExplorerWatcherThread() {
    checkTrayIconThread = new Thread() {
        @Override
        public void run() {
            int prevProcessId = 0;
            int currProcessId = 0;
            while (isRunning) {
                try {
                    //Get the current process id from another method 
                    currProcessId = explorerPid();
                    // Set initial process ID
                    if (prevProcessId == 0) {
                        prevProcessId = currProcessId;
                    }
                    //thread sleeps for 10 sec and then checks again
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    System.out.println(e.toString());
                } catch (IOException e) {
                    System.out.println(e.toString());
                }


                //Check if the process id has changed or not
                if (prevProcessId != currProcessId) {
                    prevProcessId = currProcessId;
                    // call to the method that disposes the old icon and creates a new one and registers it
                    createNewTrayIcon();
                } else {
                    System.out.println("Windows Explorer stable.");
                }
            }
        }
    };
    //Start the thread
    checkTrayIconThread.start();
}

public int explorerPid() throws IOException {
    //List<Integer> used as might be more than one explorer process at a time
    List < Integer > pidArray = new ArrayList < > ();
    String pid;
    String bufferString;
    //Windows command prompt to retrive the pid of explorer process
    String cmd = "cmd.exe /c tasklist /FI \"IMAGENAME eq explorer.exe\ " /FO LIST | findstr \"PID:";
    //Execute cmd prompt
    Process cmdProcess = Runtime.getRuntime().exec(cmd);
    cmdProcess.getOutputStream().close();
    //Read the output of the execution
    BufferedReader stdout = new BufferedReader(new InputStreamReader(cmdProcess.getInputStream()));
    //Add all the pid Integer values to the list from output
    while ((bufferString = stdout.readLine()) != null) {
        pid = bufferString;
        pid = (pid.replaceAll("\\s", "")).replace("PID:", "");
        pidArray.add(Integer.valueOf(pid));
    }
    stdout.close();

    //Return lowest value from the array
    return Collections.min(pidArray);
}

Upvotes: 0

Angeline
Angeline

Reputation: 57

Just in case anyone else stumbles across this and wonders what happened, in the end I had to stick with removing and adding the icon after a few seconds, because Windows does not update the JVM on the status of the tray icons... It was naturally not the best way to fix it, but there didn't seem to be a better way.

Upvotes: 0

9000
9000

Reputation: 40894

Just a guess.

Check for pid of explorer.exe once in a few seconds. If it has changed, unregister your tray icon and register it again.

Upvotes: 2

Related Questions