[ACCEPTED]-Need a way to check status of Windows service programmatically-windows-services
here's what I had to do. It's ugly, but 4 it works beautifully.
String STATE_PREFIX = "STATE : ";
String s = runProcess("sc query \""+serviceName+"\"");
// check that the temp string contains the status prefix
int ix = s.indexOf(STATE_PREFIX);
if (ix >= 0) {
// compare status number to one of the states
String stateStr = s.substring(ix+STATE_PREFIX.length(), ix+STATE_PREFIX.length() + 1);
int state = Integer.parseInt(stateStr);
switch(state) {
case (1): // service stopped
break;
case (4): // service started
break;
}
}
runProcess
is a private method 3 that runs the given string as a command 2 line process and returns the resulting output. As 1 I said, ugly, but works. Hope this helps.
You can create a small VBS on-th-fly, launch 1 it and capture its return code.
import java.io.File;
import java.io.FileWriter;
public class VBSUtils {
private VBSUtils() { }
public static boolean isServiceRunning(String serviceName) {
try {
File file = File.createTempFile("realhowto",".vbs");
file.deleteOnExit();
FileWriter fw = new java.io.FileWriter(file);
String vbs = "Set sh = CreateObject(\"Shell.Application\") \n"
+ "If sh.IsServiceRunning(\""+ serviceName +"\") Then \n"
+ " wscript.Quit(1) \n"
+ "End If \n"
+ "wscript.Quit(0) \n";
fw.write(vbs);
fw.close();
Process p = Runtime.getRuntime().exec("wscript " + file.getPath());
p.waitFor();
return (p.exitValue() == 1);
}
catch(Exception e){
e.printStackTrace();
}
return false;
}
public static void main(String[] args){
//
// DEMO
//
String result = "";
msgBox("Check if service 'Themes' is running (should be yes)");
result = isServiceRunning("Themes") ? "" : " NOT ";
msgBox("service 'Themes' is " + result + " running ");
msgBox("Check if service 'foo' is running (should be no)");
result = isServiceRunning("foo") ? "" : " NOT ";
msgBox("service 'foo' is " + result + " running ");
}
public static void msgBox(String msg) {
javax.swing.JOptionPane.showConfirmDialog((java.awt.Component)
null, msg, "VBSUtils", javax.swing.JOptionPane.DEFAULT_OPTION);
}
}
Based on the other answers I constructed 2 the following code to check for Windows 1 Service status:
public void checkService() {
String serviceName = "myService";
try {
Process process = new ProcessBuilder("C:\\Windows\\System32\\sc.exe", "query" , serviceName ).start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
String scOutput = "";
// Append the buffer lines into one string
while ((line = br.readLine()) != null) {
scOutput += line + "\n" ;
}
if (scOutput.contains("STATE")) {
if (scOutput.contains("RUNNING")) {
System.out.println("Service running");
} else {
System.out.println("Service stopped");
}
} else {
System.out.println("Unknown service");
}
} catch (IOException e) {
e.printStackTrace();
}
}
I have been dealing with installers for 9 years and the trick is to create your own 8 EXE and call it on setup. This offers good 7 flexibility like displaying precise error 6 messages in the event an error occurs, and 5 have success-based return values so your 4 installer knows about what happened.
Here's 3 how to start, stop and query states for 2 windows services (C++): http://msdn.microsoft.com/en-us/library/ms684941(VS.85).aspx (VB and C# offers 1 similar functions)
I have had some luck in the past with the 7 Java Service Wrapper. Depending upon your 6 situation you may need to pay in order to 5 use it. But it offers a clean solution that 4 supports Java and could be used in the InstallAnywhere 3 environment with (I think) little trouble. This 2 will also allow you to support services 1 on Unix boxes as well.
A shot in the dark but take a look at your 2 Install Anywhere java documentation.
Specifically,
/javadoc/com/installshield/wizard/platform/win32/Win32Service.html
The 1 class:
com.installshield.wizard.platform.win32
Interface Win32Service
All Superinterfaces:
Service
The method:
public NTServiceStatus queryNTServiceStatus(String name)
throws ServiceException
Calls the Win32 QueryServiceStatus to retrieve the status of the specified service. See the Win32 documentation for this API for more information.
Parameters:
name - The internal name of the service.
Throws:
ServiceException
Here's a straignt C# / P/Invoke solution.
/// <summary>
/// Returns true if the specified service is running, or false if it is not present or not running.
/// </summary>
/// <param name="serviceName">Name of the service to check.</param>
/// <returns>Returns true if the specified service is running, or false if it is not present or not running.</returns>
static bool IsServiceRunning(string serviceName)
{
bool rVal = false;
try
{
IntPtr smHandle = NativeMethods.OpenSCManager(null, null, NativeMethods.ServiceAccess.ENUMERATE_SERVICE);
if (smHandle != IntPtr.Zero)
{
IntPtr svHandle = NativeMethods.OpenService(smHandle, serviceName, NativeMethods.ServiceAccess.ENUMERATE_SERVICE);
if (svHandle != IntPtr.Zero)
{
NativeMethods.SERVICE_STATUS servStat = new NativeMethods.SERVICE_STATUS();
if (NativeMethods.QueryServiceStatus(svHandle, servStat))
{
rVal = servStat.dwCurrentState == NativeMethods.ServiceState.Running;
}
NativeMethods.CloseServiceHandle(svHandle);
}
NativeMethods.CloseServiceHandle(smHandle);
}
}
catch (System.Exception )
{
}
return rVal;
}
public static class NativeMethods
{
[DllImport("AdvApi32")]
public static extern IntPtr OpenSCManager(string machineName, string databaseName, ServiceAccess access);
[DllImport("AdvApi32")]
public static extern IntPtr OpenService(IntPtr serviceManagerHandle, string serviceName, ServiceAccess access);
[DllImport("AdvApi32")]
public static extern bool CloseServiceHandle(IntPtr serviceHandle);
[DllImport("AdvApi32")]
public static extern bool QueryServiceStatus(IntPtr serviceHandle, [Out] SERVICE_STATUS status);
[Flags]
public enum ServiceAccess : uint
{
ALL_ACCESS = 0xF003F,
CREATE_SERVICE = 0x2,
CONNECT = 0x1,
ENUMERATE_SERVICE = 0x4,
LOCK = 0x8,
MODIFY_BOOT_CONFIG = 0x20,
QUERY_LOCK_STATUS = 0x10,
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000
}
public enum ServiceState
{
Stopped = 1,
StopPending = 3,
StartPending = 2,
Running = 4,
Paused = 7,
PausePending =6,
ContinuePending=5
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SERVICE_STATUS
{
public int dwServiceType;
public ServiceState dwCurrentState;
public int dwControlsAccepted;
public int dwWin32ExitCode;
public int dwServiceSpecificExitCode;
public int dwCheckPoint;
public int dwWaitHint;
};
}
0
I improvised on the given solutions, to 8 make it locale independent. Comparing the 7 string "RUNNING" would not work 6 in systems with non-english locales as Alejandro González rightly pointed out.
I 5 made use of sc interrogate and look for the status codes 4 returned by it.
Mainly, the service can have 3 3 states:-
1 - Not available
[SC] OpenService FAILED 1060: The specified service does not exist as an installed service.
2 - Not running
([SC] ControlService FAILED 1062: The service has not been started)
3 2 - Running
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 21100code here
So using them in following code, gives 1 us the desired result :-
public static void checkBackgroundService(String serviceName) {
Process process;
try {
process = Runtime.getRuntime().exec("sc interrogate " + serviceName);
Scanner reader = new Scanner(process.getInputStream(), "UTF-8");
StringBuffer buffer = new StringBuffer();
while (reader.hasNextLine()) {
buffer.append(reader.nextLine());
}
System.out.println(buffer.toString());
if (buffer.toString().contains("1060:")) {
System.out.println("Specified Service does not exist");
} else if (buffer.toString().contains("1062:")) {
System.out.println("Specified Service is not started (not running)");
} else {
System.out.println("Specified Service is running");
}
} catch (IOException e) {
e.printStackTrace();
}
}
During startup, create a file with File.deleteOnExit().
Check 1 for the existence of the file in your scripts.
Simply call this method to check the status 1 of service whether running or not.
public boolean checkIfServiceRunning(String serviceName) {
Process process;
try {
process = Runtime.getRuntime().exec("sc query " + serviceName);
Scanner reader = new Scanner(process.getInputStream(), "UTF-8");
while(reader.hasNextLine()) {
if(reader.nextLine().contains("RUNNING")) {
return true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.