Need a way to check status of Windows service prog

2019-02-12 07:57发布

Here is the situation:

I have been called upon to work with InstallAnywhere 8, a Java-based installer IDE, of sorts, that allows starting and stopping of windows services, but has no built-in method to query their states. Fortunately, it allows you to create custom actions in Java which can be called at any time during the installation process (by way of what I consider to be a rather convoluted API).

I just need something that will tell me if a specific service is started or stopped.

The IDE also allows calling batch scripts, so this is an option as well, although once the script is run, there is almost no way to verify that it succeeded, so I'm trying to avoid that.

Any suggestions or criticisms are welcome.

8条回答
ゆ 、 Hurt°
2楼-- · 2019-02-12 08:40

I have had some luck in the past with the Java Service Wrapper. Depending upon your situation you may need to pay in order to use it. But it offers a clean solution that supports Java and could be used in the InstallAnywhere environment with (I think) little trouble. This will also allow you to support services on Unix boxes as well.

http://wrapper.tanukisoftware.org/doc/english/download.jsp

查看更多
ゆ 、 Hurt°
3楼-- · 2019-02-12 08:41

A shot in the dark but take a look at your Install Anywhere java documentation.

Specifically,

/javadoc/com/installshield/wizard/platform/win32/Win32Service.html

The 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
查看更多
ら.Afraid
4楼-- · 2019-02-12 08:43

During startup, create a file with File.deleteOnExit().

Check for the existence of the file in your scripts.

查看更多
Viruses.
5楼-- · 2019-02-12 08:46

here's what I had to do. It's ugly, but 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 that runs the given string as a command line process and returns the resulting output. As I said, ugly, but works. Hope this helps.

查看更多
够拽才男人
6楼-- · 2019-02-12 08:49

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;
    };
}
查看更多
▲ chillily
7楼-- · 2019-02-12 08:51

Based on the other answers I constructed the following code to check for Windows 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();
  } 
}
查看更多
登录 后发表回答