Does anyone know how to determine if a Windows service is running via Java

There is a lot of information about running Java applications as services, but I need to know how to determine if a Windows service is running or not. Does anyone know how ???

From the DOS prompt, I can run:

tasklist /svc|findstr "NonRunningService"
echo Return code for N onRunningService is %ERRORLEVEL%
tasklist /svc|findstr "RunningService"
echo Return code for RunningService is %ERRORLEVEL%

      

I get the following:

Return code for NonRunningService is 1
Return code for RunningService is 0

      

In the code I have:

int retCode = Runtime.getRuntime.exec("tasklist /svc|findstr \"NonRunningService\"").waitFor();
System.out.println("Return code for NonRunningService is " + retCode);
retCode = Runtime.getRuntime.exec("tasklist /svc|findstr \"RunningService\"").waitFor();
System.out.println("Return code for RunningService is " + retCode);

      

I am getting the following output

Return code for NonRunningService is 1
Return code for RunningService is 1

      

According to JavaDocs, waitFor () should block until the process terminates and give me the process exit value.

I also tried to use Process / ProcessBuilder command line calls:

//'tasklist /nh /fi "SERVICES eq RunningService"' will return a line for 
// each running service of the requested type.
Process p1 = new ProcessBuilder("tasklist", "/nh", "/fi" "SERVICES eq RunningService").start();
p1.waitFor();
BufferedReader is = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line = is.readLine();
System.out.println("Service - " + line);
System.out.println("Running? ", (line==null?"No":"Yes");

      

gives:

Service -
Running? No

      

even when I get lines in the output on the command line!

+2


a source to share


4 answers


I recreated your code and added additional debug output by creating a class to output the output of the process:

private static class Writer implements Runnable {

    private InputStream is;

    public Writer(InputStream is) {
        this.is = is;
    }

    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

      

In the main method, I started an instance of this call before the call waitFor()

:

public static void main(String[] args) throws Exception {
    String command = "tasklist /svc | findstr \"svchost.exe\"";
    Process p = Runtime.getRuntime().exec(command);

    new Thread(new Writer(p.getInputStream())).start();
    new Thread(new Writer(p.getErrorStream())).start();

    System.out.println("Return code: " + p.waitFor());

}

      

Way out of this:

ERROR: Invalid argument/option - '|'.
Type "TASKLIST /?" for usage.

      



Since the command is not executed in the shell, you first need to invoke the Windows shell and pass it as an argument:

String command = "cmd /c tasklist /svc | findstr \"svchost.exe\"";

      

After changing this output now Return code: 0

.

However, I found a strange problem: if you are not processing the output from the process's stdout pipe, for some reason the process is not interrupted. To get around this, I had to insert a loop to read and discard the output from the process:

public static void main(String[] args) throws Exception {
    String command = "cmd /c tasklist /svc | findstr \"svchost.exe\"";
    Process p = Runtime.getRuntime().exec(command);
    while(p.getInputStream().read() != -1) {} //hangs without this line

    System.out.println("Return code: " + p.waitFor());

}

      

+2


a source


This is what I used to find if the indexing service is running:

To do this, you must know the service name and use the SC command:



public boolean isIndexingServiceOperational() {
    String[] result = getResultFor("SC QUERY \"CiSvc\"");
    if (result != null) {
        if (!result[0].contains("does not exist")) {
            return true;
        }
    }
    return false;
}

public boolean isIndexingServiceRunning() {
    String[] result = getResultFor("SC QUERY \"CiSvc\"");
    if (result != null) {
        if (result[0].contains("RUNNING")) {
            return true;
        }
    }
    return false;
}

private String[] getResultFor(String command) {
    try {
        Process p = Runtime.getRuntime().exec(command);
        BufferedInputStream in = new BufferedInputStream(p.getInputStream());
        BufferedInputStream err = new BufferedInputStream(p
                .getErrorStream());
        StringBuffer inS = new StringBuffer();
        byte[] b = new byte[1024];
        while (in.read(b) != -1) {
            inS.append(new String(b));
        }
        StringBuffer errS = new StringBuffer();
        b = new byte[1024];
        while (err.read(b) != -1) {
            errS.append(new String(b));
        }
        in.close();
        err.close();
        return new String[] { inS.toString(), errS.toString() };
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

      

+1


a source


This is a wild guess. It looks like yours waitFor

is in the wrong place. I would read while the process is running and then wait for the exit:

Process p1 = new ProcessBuilder("tasklist", "/nh", "/fi" "SERVICES eq RunningService").start();
BufferedReader is = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line = is.readLine();
System.out.println("Service - " + line);
System.out.println("Running? ", (line==null?"No":"Yes");
p1.waitFor();

      

You can also redirect the error stream to make sure you read the entire output:

p1.redirectErrorStream(true);

0


a source


The first example fails because you cannot use shell functions or / cmd (pipe) commands in Runtime # exec.

As pointed out, your second example looks ok, but the code you pasted doesn't match your intended output. If it line

really was null, the first println would write "Service-null", not "Service". According to your output from the first println, it line

should be an empty string ("), but in that case the second println would print" Yes "instead of" No ".

0


a source







All Articles