Кто-нибудь знает, как определить, работает ли служба Windows через Java - PullRequest
2 голосов
/ 13 апреля 2010

Существует много информации о запуске приложений Java как сервисов, но мне нужно знать, как определить, запущена ли служба Windows или нет. Кто-нибудь знает как ???

В командной строке DOS я могу запустить:

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

Я получаю следующее:

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

В коде у меня есть:

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);

Я получаю следующий вывод

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

Согласно JavaDocs, waitFor () должен блокироваться до завершения процесса и давать мне выходное значение процесса.

Я также пытался использовать вызовы командной строки Process / ProcessBuilder:

//'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");

дает:

Service -
Running? No

даже когда я получаю строки в выводе в командной строке!

Ответы [ 4 ]

2 голосов
/ 13 апреля 2010

Я заново создал ваш код и добавил некоторые дополнительные выходные данные отладки, создав класс для печати выходных данных процесса:

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();
        }
}

В основном методе я запустил экземпляр этого перед вызовом 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());

}

Вывод этого:

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

Поскольку команда не выполняется в оболочке, сначала необходимо вызвать оболочку Windows и передать команду какаргумент:

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

После изменения этого результата теперь вывод Return code: 0.

Однако я обнаружил странную проблему, заключающуюся в том, что если вы не обрабатываете вывод из канала вывода процесса, по какой-то причине процесс не завершается.Чтобы обойти это, мне пришлось вставить цикл для чтения и отбрасывания вывода процесса:

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());

}
1 голос
/ 13 апреля 2010

Это то, что я использовал, чтобы узнать, работает ли служба индексирования:

Чтобы сделать это, вы должны знать имя службы и использовать команду SC:

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;
}
0 голосов
/ 13 апреля 2010

Ваш первый пример терпит неудачу, так как вы не можете использовать функции (каналы) оболочки или команды / cmd в Runtime # exec.

Как уже указывалось, ваш второй пример выглядит нормально, но вставленный вами код не соответствует вашему предполагаемому выводу. Если бы line действительно было нулевым, в первом println было бы написано "Service - null", а не "Service -". Согласно вашему выводу из первого println, line должно быть пустой строкой (""), но в этом случае второй println напечатал бы "Да" вместо "Нет".

0 голосов
/ 13 апреля 2010

Это дикая догадка.Похоже, ваш waitFor не в том месте.Я бы прочитал, пока процесс запущен, затем дождался выхода:

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();

Вы также можете перенаправить поток ошибок, чтобы убедиться, что вы прочитали все выходные данные:

p1.redirectErrorStream(true);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...