Need a way to check status of Windows service programmatically

前端 未结 9 883
走了就别回头了
走了就别回头了 2021-01-04 10:11

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 ser

相关标签:
9条回答
  • 2021-01-04 10:44

    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();
      } 
    }
    
    0 讨论(0)
  • 2021-01-04 10:44

    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 讨论(0)
  • 2021-01-04 10:49

    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.

    0 讨论(0)
提交回复
热议问题