Win32ServiceController.cs :  » 2.6.4-mono-.net-core » System.ServiceModel » System » ServiceProcess » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.ServiceModel 
System.ServiceModel » System » ServiceProcess » Win32ServiceController.cs
//
// System.ServiceProcess.Win32ServiceController
//
// Author:
//  Gert Driesen (drieseng@users.sourceforge.net)
//
// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;

namespace System.ServiceProcess{
  internal class Win32ServiceController : ServiceControllerImpl
  {
    SERVICE_STATUS_PROCESS _status;

    public Win32ServiceController (ServiceController serviceController)
      : base (serviceController)
    {
    }

    public override bool CanPauseAndContinue {
      get {
        if ((int) _status.dwServiceType == 0)
          _status = GetServiceStatus (ServiceController.ServiceName,
            ServiceController.MachineName);
        return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_PAUSE_CONTINUE) != 0;
      }
    }

    public override bool CanShutdown {
      get {
        if ((int) _status.dwServiceType == 0)
          _status = GetServiceStatus (ServiceController.ServiceName,
            ServiceController.MachineName);
        return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_SHUTDOWN) != 0;
      }
    }

    public override bool CanStop {
      get {
        if ((int) _status.dwServiceType == 0)
          _status = GetServiceStatus (ServiceController.ServiceName,
            ServiceController.MachineName);
        return (_status.dwControlsAccepted & SERVICE_CONTROL_ACCEPTED.SERVICE_ACCEPT_STOP) != 0;
      }
    }

    public override ServiceController [] DependentServices {
      get {
        return GetDependentServices (ServiceController.ServiceName,
          ServiceController.MachineName);
      }
    }

    public override string DisplayName {
      get {
        string lookupName = ServiceController.ServiceName;

        IntPtr scHandle = IntPtr.Zero;
        try {
          scHandle = OpenServiceControlManager (ServiceController.MachineName,
            SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);
          if (lookupName.Length == 0) {
            // if the service name is not available, then
            // assume the specified name is in fact already a display
            // name
            try {
              string serviceName = GetServiceName (scHandle, 
                lookupName);
              ServiceController.InternalServiceName = serviceName;
              ServiceController.Name = string.Empty;
              return lookupName;
            } catch (Win32Exception) {
            }
          }

          if (ServiceController.InternalDisplayName.Length == 0)
            return GetServiceDisplayName (scHandle, lookupName,
              ServiceController.MachineName);
          return ServiceController.InternalDisplayName;
        } finally {
          if (scHandle != IntPtr.Zero)
            CloseServiceHandle (scHandle);
        }
      }
    }

    public override string ServiceName {
      get {
        string lookupName = ServiceController.Name;
        if (lookupName.Length == 0)
          lookupName = ServiceController.InternalDisplayName;

        IntPtr scHandle = IntPtr.Zero;
        try {
          scHandle = OpenServiceControlManager (ServiceController.MachineName,
            SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

          // assume the specified name is in fact a display name
          try {
            string serviceName = GetServiceName (scHandle, lookupName);
            ServiceController.InternalDisplayName = lookupName;
            ServiceController.Name = string.Empty;
            return serviceName;
          } catch (Win32Exception) {
          }

          // instead of opening the service to verify whether it exists,
          // we'll try to get its displayname and hereby avoid looking
          // this up separately
          string displayName = GetServiceDisplayName (scHandle,
            lookupName, ServiceController.MachineName);
          ServiceController.InternalDisplayName = displayName;
          ServiceController.Name = string.Empty;
          return lookupName;
        } finally {
          if (scHandle != IntPtr.Zero)
            CloseServiceHandle (scHandle);
        }
      }
    }

    public override ServiceController [] ServicesDependedOn {
      get {
        return GetServiceDependencies (ServiceController.ServiceName,
          ServiceController.MachineName);
      }
    }

    public override ServiceType ServiceType {
      get {
        if ((int) _status.dwServiceType == 0)
          _status = GetServiceStatus (ServiceController.ServiceName,
            ServiceController.MachineName);
        return _status.dwServiceType;
      }
    }

    public override ServiceControllerStatus Status {
      get {
        if ((int) _status.dwServiceType == 0)
          _status = GetServiceStatus (ServiceController.ServiceName,
            ServiceController.MachineName);
        return _status.dwCurrentState;
      }
    }

    public override void Close ()
    {
      // clear status cache
      _status.dwServiceType = 0;
    }

    public override void Continue ()
    {
      string serviceName = ServiceController.ServiceName;
      string machineName = ServiceController.MachineName;
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_PAUSE_CONTINUE);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName,
            machineName);

        SERVICE_STATUS status = new SERVICE_STATUS ();
        if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_CONTINUE, ref status))
          throw new InvalidOperationException (string.Format (
            CultureInfo.CurrentCulture, "Cannot resume {0} service"
            + " on computer '{1}'.", serviceName, machineName),
            new Win32Exception ());
      } finally {
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
      }
    }

    public override void Dispose (bool disposing)
    {
      // we're not keeping any handles open
    }

    public override void ExecuteCommand (int command)
    {
      string serviceName = ServiceController.ServiceName;
      string machineName = ServiceController.MachineName;
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        // MSDN: the hService handle must have the SERVICE_USER_DEFINED_CONTROL
        // access right
        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_USER_DEFINED_CONTROL);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName,
            machineName);

        SERVICE_STATUS status = new SERVICE_STATUS ();
        if (!ControlService (svcHandle, (SERVICE_CONTROL_TYPE) command, ref status))
          throw new InvalidOperationException (string.Format (
            CultureInfo.CurrentCulture, "Cannot control {0} service"
            + " on computer '{1}'.", serviceName, machineName),
            new Win32Exception ());
      } finally {
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
      }
    }

    public override ServiceController [] GetDevices ()
    {
      return GetServices (ServiceController.MachineName,
        SERVICE_TYPE.SERVICE_DRIVER, null);
    }

    public override ServiceController [] GetServices ()
    {
      return GetServices (ServiceController.MachineName,
        SERVICE_TYPE.SERVICE_WIN32, null);
    }

    public override void Pause ()
    {
      string serviceName = ServiceController.ServiceName;
      string machineName = ServiceController.MachineName;
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_PAUSE_CONTINUE);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName,
            machineName);

        SERVICE_STATUS status = new SERVICE_STATUS ();
        if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_PAUSE, ref status))
          throw new InvalidOperationException (string.Format (
            CultureInfo.CurrentCulture, "Cannot pause {0} service"
            + " on computer '{1}'.", serviceName, machineName),
            new Win32Exception ());
      } finally {
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
      }
    }

    public override void Refresh ()
    {
      // force refresh of status
      _status.dwServiceType = 0;
    }

    public override void Start (string [] args)
    {
      string serviceName = ServiceController.ServiceName;
      string machineName = ServiceController.MachineName;
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;
      IntPtr [] arguments = new IntPtr [args.Length];

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_START);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName,
            machineName);

        for (int i = 0; i < args.Length; i++) {
          string argument = args [i];
          arguments [i] = Marshal.StringToHGlobalAnsi (argument);
        }

        if (!StartService (svcHandle, arguments.Length, arguments))
          throw new InvalidOperationException (string.Format (
            CultureInfo.CurrentCulture, "Cannot start {0} service"
            + " on computer '{1}'.", serviceName, machineName),
            new Win32Exception ());
      } finally {
        for (int i = 0; i < arguments.Length; i++)
          Marshal.FreeHGlobal (arguments [i]);
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
      }

    }

    public override void Stop ()
    {
      string serviceName = ServiceController.ServiceName;
      string machineName = ServiceController.MachineName;
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_STOP);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName,
            machineName);

        SERVICE_STATUS status = new SERVICE_STATUS ();
        if (!ControlService (svcHandle, SERVICE_CONTROL_TYPE.SERVICE_CONTROL_STOP, ref status))
          throw new InvalidOperationException (string.Format (
            CultureInfo.CurrentCulture, "Cannot stop {0} service"
            + " on computer '{1}'.", serviceName, machineName),
            new Win32Exception ());
      } finally {
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
      }
    }

    private static ServiceController [] GetDependentServices (string serviceName, string machineName)
    {
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;
      IntPtr buffer = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_ENUMERATE_DEPENDENTS);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName, machineName);

        uint bufferSize = 0;
        uint bytesNeeded = 0;
        uint servicesReturned = 0;

        ServiceController [] services;

        while (true) {
          if (!EnumDependentServices (svcHandle, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned)) {
            int err = Marshal.GetLastWin32Error ();
            if (err == ERROR_MORE_DATA) {
              buffer = Marshal.AllocHGlobal ((int) bytesNeeded);
              bufferSize = bytesNeeded;
            } else {
              throw new Win32Exception (err);
            }
          } else {
            int iPtr = buffer.ToInt32 ();

            services = new ServiceController [servicesReturned];
            for (int i = 0; i < servicesReturned; i++) {
              ENUM_SERVICE_STATUS serviceStatus = (ENUM_SERVICE_STATUS) Marshal.PtrToStructure (
                new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS));
              // TODO: use internal ctor that takes displayname too ?
              services [i] = new ServiceController (serviceStatus.pServiceName,
                machineName);
              // move on to the next services
              iPtr += ENUM_SERVICE_STATUS.SizeOf;
            }

            // we're done, so exit the loop
            break;
          }
        }

        return services;
      } finally {
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (buffer != IntPtr.Zero)
          Marshal.FreeHGlobal (buffer);
      }
    }

    private static ServiceController [] GetServiceDependencies (string serviceName, string machineName)
    {
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;
      IntPtr buffer = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_QUERY_CONFIG);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName, machineName);

        uint bufferSize = 0;
        uint bytesNeeded = 0;

        ServiceController [] services;

        while (true) {
          if (!QueryServiceConfig (svcHandle, buffer, bufferSize, out bytesNeeded)) {
            int err = Marshal.GetLastWin32Error ();
            if (err == ERROR_INSUFFICIENT_BUFFER) {
              buffer = Marshal.AllocHGlobal ((int) bytesNeeded);
              bufferSize = bytesNeeded;
            } else {
              throw new Win32Exception (err);
            }
          } else {
            QUERY_SERVICE_CONFIG config = (QUERY_SERVICE_CONFIG) Marshal.PtrToStructure (
              buffer, typeof (QUERY_SERVICE_CONFIG));

            Hashtable depServices = new Hashtable ();
            IntPtr iPtr = config.lpDependencies;
            StringBuilder sb = new StringBuilder ();
            string currentChar = Marshal.PtrToStringUni (iPtr, 1);
            while (currentChar != "\0") {
              sb.Append (currentChar);
              iPtr = new IntPtr (iPtr.ToInt64 () + Marshal.SystemDefaultCharSize);
              currentChar = Marshal.PtrToStringUni (iPtr, 1);
              if (currentChar != "\0") {
                continue;
              }
              iPtr = new IntPtr (iPtr.ToInt64 () + Marshal.SystemDefaultCharSize);
              currentChar = Marshal.PtrToStringUni (iPtr, 1);
              string dependency = sb.ToString ();
              if (dependency [0] == SC_GROUP_IDENTIFIER) {
                ServiceController [] groupServices = GetServices (
                  machineName, SERVICE_TYPE.SERVICE_WIN32,
                  dependency.Substring (1));
                foreach (ServiceController sc in groupServices) {
                  if (!depServices.Contains (sc.ServiceName))
                    depServices.Add (sc.ServiceName, sc);
                }
              } else if (!depServices.Contains (dependency)) {
                depServices.Add (dependency, new ServiceController (dependency, machineName));
              }
              sb.Length = 0;
            }

            services = new ServiceController [depServices.Count];
            depServices.Values.CopyTo (services, 0);
            break;
          }
        }

        return services;
      } finally {
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (buffer != IntPtr.Zero)
          Marshal.FreeHGlobal (buffer);
      }
    }

    private static string GetServiceDisplayName (IntPtr scHandle, string serviceName, string machineName)
    {
      StringBuilder buffer = new StringBuilder ();

      uint bufferSize = (uint) buffer.Capacity;

      while (true) {
        if (!GetServiceDisplayName (scHandle, serviceName, buffer, ref bufferSize)) {
          int err = Marshal.GetLastWin32Error ();
          if (err == ERROR_INSUFFICIENT_BUFFER) {
            // allocate additional byte for terminating null char
            buffer = new StringBuilder ((int) bufferSize + 1);
            bufferSize = (uint) buffer.Capacity;
          } else {
            throw new InvalidOperationException (string.Format (
              CultureInfo.CurrentCulture, "Service {0} was not"
              + " found on computer '{1}'.", serviceName,
              machineName), new Win32Exception ());
          }
        } else {
          return buffer.ToString ();
        }
      }
    }

    private static string GetServiceName (IntPtr scHandle, string displayName)
    {
      StringBuilder buffer = new StringBuilder ();

      uint bufferSize = (uint) buffer.Capacity;

      while (true) {
        if (!GetServiceKeyName (scHandle, displayName, buffer, ref bufferSize)) {
          int err = Marshal.GetLastWin32Error ();
          if (err == ERROR_INSUFFICIENT_BUFFER) {
            // allocate additional byte for terminating null char
            buffer = new StringBuilder ((int) bufferSize + 1);
            bufferSize = (uint) buffer.Capacity;
          } else {
            throw new Win32Exception ();
          }
        } else {
          return buffer.ToString ();
        }
      }
    }

    private static SERVICE_STATUS_PROCESS GetServiceStatus (string serviceName, string machineName)
    {
      IntPtr scHandle = IntPtr.Zero;
      IntPtr svcHandle = IntPtr.Zero;
      IntPtr buffer = IntPtr.Zero;

      try {
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT);

        svcHandle = OpenService (scHandle, serviceName, SERVICE_RIGHTS.SERVICE_QUERY_STATUS);
        if (svcHandle == IntPtr.Zero)
          throw CreateCannotOpenServiceException (serviceName, machineName);

        int bufferSize = 0;
        int bytesNeeded = 0;

        while (true) {
          if (!QueryServiceStatusEx (svcHandle, SC_STATUS_PROCESS_INFO, buffer, bufferSize, out bytesNeeded)) {
            int err = Marshal.GetLastWin32Error ();
            if (err == ERROR_INSUFFICIENT_BUFFER) {
              buffer = Marshal.AllocHGlobal (bytesNeeded);
              bufferSize = bytesNeeded;
            } else {
              throw new Win32Exception (err);
            }
          } else {
            SERVICE_STATUS_PROCESS serviceStatus = (SERVICE_STATUS_PROCESS) Marshal.PtrToStructure (
              buffer, typeof (SERVICE_STATUS_PROCESS));
            return serviceStatus;
          }
        }
      } finally {
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
        if (svcHandle != IntPtr.Zero)
          CloseServiceHandle (svcHandle);
        if (buffer != IntPtr.Zero)
          Marshal.FreeHGlobal (buffer);
      }
    }

    private static ServiceController [] GetServices (string machineName, SERVICE_TYPE serviceType, string group)
    {
      IntPtr scHandle = IntPtr.Zero;
      IntPtr buffer = IntPtr.Zero;

      try {
#if NET_2_0
        scHandle = OpenServiceControlManager (machineName, 
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE);
#else
        scHandle = OpenServiceControlManager (machineName,
          SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE, true);
#endif

        uint bufferSize = 0;
        uint bytesNeeded = 0;
        uint servicesReturned = 0;
        uint resumeHandle = 0;

        ServiceController [] services;

        while (true) {
          if (!EnumServicesStatusEx (scHandle, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned, ref resumeHandle, group)) {
            int err = Marshal.GetLastWin32Error ();
            if (err == ERROR_MORE_DATA) {
              buffer = Marshal.AllocHGlobal ((int) bytesNeeded);
              bufferSize = bytesNeeded;
            } else {
              throw new Win32Exception (err);
            }
          } else {
            int iPtr = buffer.ToInt32 ();

            services = new ServiceController [servicesReturned];
            for (int i = 0; i < servicesReturned; i++) {
              ENUM_SERVICE_STATUS_PROCESS serviceStatus = (ENUM_SERVICE_STATUS_PROCESS) Marshal.PtrToStructure (
                new IntPtr (iPtr), typeof (ENUM_SERVICE_STATUS_PROCESS));
              // TODO: use internal ctor that takes displayname too
              services [i] = new ServiceController (serviceStatus.pServiceName,
                machineName);
              // move on to the next services
              iPtr += ENUM_SERVICE_STATUS_PROCESS.SizeOf;
            }

            // we're done, so exit the loop
            break;
          }
        }

        return services;
      } finally {
        if (scHandle != IntPtr.Zero)
          CloseServiceHandle (scHandle);
        if (buffer != IntPtr.Zero)
          Marshal.FreeHGlobal (buffer);
      }
    }

    private static IntPtr OpenServiceControlManager (string machineName, SERVICE_MANAGER_RIGHTS rights)
    {
      return OpenServiceControlManager (machineName, rights, false);
    }

    private static IntPtr OpenServiceControlManager (string machineName, SERVICE_MANAGER_RIGHTS rights, bool ignoreWin32Error)
    {
        IntPtr scHandle = OpenSCManager (machineName, SERVICES_ACTIVE_DATABASE,
          rights);
        if (scHandle == IntPtr.Zero) {
          string msg = string.Format (CultureInfo.CurrentCulture,
            "Cannot open Service Control Manager on computer '{0}'."
            + " This operation might require other priviliges.",
            machineName);
          if (ignoreWin32Error)
            throw new InvalidOperationException (msg);
          throw new InvalidOperationException (msg, new Win32Exception ());
        }
        return scHandle;
    }

    private static InvalidOperationException CreateCannotOpenServiceException (string serviceName, string machineName)
    {
      return new InvalidOperationException (string.Format (CultureInfo.CurrentCulture,
        "Cannot open {0} service on computer '{1}'.", serviceName, machineName),
        new Win32Exception ());
    }

    #region PInvoke declaration

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern void CloseServiceHandle (IntPtr SCHANDLE);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool ControlService (
      IntPtr hService,
      SERVICE_CONTROL_TYPE dwControl,
      ref SERVICE_STATUS lpServiceStatus);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool EnumDependentServices (
      IntPtr hService,
      SERVICE_STATE_REQUEST dwServiceState,
      IntPtr lpServices,
      uint cbBufSize,
      out uint pcbBytesNeeded,
      out uint lpServicesReturned);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool EnumServicesStatusEx (
      IntPtr hSCManager,
      int InfoLevel,
      SERVICE_TYPE dwServiceType,
      SERVICE_STATE_REQUEST dwServiceState,
      IntPtr lpServices,
      uint cbBufSize,
      out uint pcbBytesNeeded,
      out uint lpServicesReturned,
      ref uint lpResumeHandle,
      string pszGroupName);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool GetServiceDisplayName (
      IntPtr hSCManager,
      string lpServiceName,
      StringBuilder lpDisplayName,
      ref uint lpcchBuffer);

    [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool GetServiceKeyName (
      IntPtr hSCManager,
      string lpDisplayName,
      StringBuilder lpServiceName,
      ref uint lpcchBuffer);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr OpenSCManager (
      string lpMachineName,
      string lpSCDB,
      SERVICE_MANAGER_RIGHTS scParameter);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern IntPtr OpenService (
      IntPtr SCHANDLE,
      string lpSvcName,
      SERVICE_RIGHTS dwNumServiceArgs);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool QueryServiceConfig (
      IntPtr hService,
      IntPtr lpServiceConfig,
      uint cbBufSize,
      out uint pcbBytesNeeded);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool QueryServiceStatusEx (
      IntPtr serviceHandle,
      int InfoLevel,
      IntPtr lpBuffer,
      int cbBufSize,
      out int pcbBytesNeeded);

    [DllImport ("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern bool StartService (
      IntPtr SVHANDLE,
      int dwNumServiceArgs,
      IntPtr [] lpServiceArgVectors);

    private const int SC_ENUM_PROCESS_INFO = 0;
    private const char SC_GROUP_IDENTIFIER = '+';
    private const int SC_STATUS_PROCESS_INFO = 0;
    private const int SERVICE_NO_CHANGE = -1;
    private const int ERROR_MORE_DATA = 234;
    private const int ERROR_INSUFFICIENT_BUFFER = 122;
    private const int STANDARD_RIGHTS_REQUIRED = 0xf0000;
    private const string SERVICES_ACTIVE_DATABASE = "ServicesActive";

    internal struct QUERY_SERVICE_CONFIG
    {
      public int dwServiceType;
      public int dwStartType;
      public int dwErrorControl;
      public IntPtr lpBinaryPathName;
      public IntPtr lpLoadOrderGroup;
      public int dwTagId;
      public IntPtr lpDependencies;
      public IntPtr lpServiceStartName;
      public IntPtr lpDisplayName;
    }

    [Flags]
    private enum SERVICE_RIGHTS
    {
      SERVICE_QUERY_CONFIG = 1,
      SERVICE_CHANGE_CONFIG = 2,
      SERVICE_QUERY_STATUS = 4,
      SERVICE_ENUMERATE_DEPENDENTS = 8,
      SERVICE_START = 16,
      SERVICE_STOP = 32,
      SERVICE_PAUSE_CONTINUE = 64,
      SERVICE_INTERROGATE = 128,
      SERVICE_USER_DEFINED_CONTROL = 256,
      SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG |
        SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS |
        SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP |
        SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE |
        SERVICE_USER_DEFINED_CONTROL)
    }

    private enum SERVICE_MANAGER_RIGHTS : uint
    {
      STANDARD_RIGHTS_READ = 0x20000,
      STANDARD_RIGHTS_WRITE = 0x20000,
      STANDARD_RIGHTS_EXECUTE = 0x20000,
      STANDARD_RIGHTS_ALL = 0x1F0000,

      SC_MANAGER_ALL_ACCESS = 0xf003f,
      SC_MANAGER_CONNECT = 1,
      SC_MANAGER_CREATE_SERVICE = 2,
      SC_MANAGER_ENUMERATE_SERVICE = 4,
      SC_MANAGER_LOCK = 8,
      SC_MANAGER_QUERY_LOCK_STATUS = 16,
      SC_MANAGER_MODIFY_BOOT_CONFIG = 32,

      GENERIC_READ = 0x80000000,
      GENERIC_WRITE = 0x40000000,
      GENERIC_EXECUTE = 0x20000000,
      GENERIC_ALL = 0x10000000
    }

    [StructLayout (LayoutKind.Sequential)]
    private struct ENUM_SERVICE_STATUS_PROCESS
    {
      public static readonly int SizeOf = Marshal.SizeOf (typeof (ENUM_SERVICE_STATUS_PROCESS));

      [MarshalAs (UnmanagedType.LPWStr)]
      public string pServiceName;

      [MarshalAs (UnmanagedType.LPWStr)]
      public string pDisplayName;

      public SERVICE_STATUS_PROCESS ServiceStatus;
    }

    [StructLayout (LayoutKind.Sequential)]
    private struct ENUM_SERVICE_STATUS
    {
      public static readonly int SizeOf = Marshal.SizeOf (typeof (ENUM_SERVICE_STATUS));

      [MarshalAs (UnmanagedType.LPWStr)]
      public string pServiceName;
      [MarshalAs (UnmanagedType.LPWStr)]
      public string pDisplayName;
      public SERVICE_STATUS ServiceStatus;
    }

    [StructLayout (LayoutKind.Sequential)]
    private struct SERVICE_STATUS
    {
      public ServiceType dwServiceType;
      public ServiceControllerStatus dwCurrentState;
      public SERVICE_CONTROL_ACCEPTED dwControlsAccepted;
      public int dwWin32ExitCode;
      public int dwServiceSpecificExitCode;
      public uint dwCheckPoint;
      public uint dwWaitHint;
    }

    [StructLayout (LayoutKind.Sequential, Pack = 1)]
    private struct SERVICE_STATUS_PROCESS
    {
      public static readonly int SizeOf = Marshal.SizeOf (typeof (SERVICE_STATUS_PROCESS));

      public ServiceType dwServiceType;
      public ServiceControllerStatus dwCurrentState;
      public SERVICE_CONTROL_ACCEPTED dwControlsAccepted;
      public int dwWin32ExitCode;
      public int dwServiceSpecificExitCode;
      public int dwCheckPoint;
      public int dwWaitHint;
      public int dwProcessId;
      public int dwServiceFlags;
    }

    private enum SERVICE_TYPE
    {
      SERVICE_KERNEL_DRIVER = 0x1,
      SERVICE_FILE_SYSTEM_DRIVER = 0x2,
      SERVICE_ADAPTER = 0x4,
      SERVICE_RECOGNIZER_DRIVER = 0x8,
      SERVICE_DRIVER = (SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER),
      SERVICE_WIN32_OWN_PROCESS = 0x10,
      SERVICE_WIN32_SHARE_PROCESS = 0x20,
      SERVICE_INTERACTIVE_PROCESS = 0x100,
      SERVICETYPE_NO_CHANGE = SERVICE_NO_CHANGE,
      SERVICE_WIN32 = (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS),
      SERVICE_TYPE_ALL = (SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS)
    }

    private enum SERVICE_START_TYPE
    {
      SERVICE_BOOT_START = 0x0,
      SERVICE_SYSTEM_START = 0x1,
      SERVICE_AUTO_START = 0x2,
      SERVICE_DEMAND_START = 0x3,
      SERVICE_DISABLED = 0x4,
      SERVICESTARTTYPE_NO_CHANGE = SERVICE_NO_CHANGE
    }

    private enum SERVICE_ERROR_CONTROL
    {
      SERVICE_ERROR_IGNORE = 0x0,
      SERVICE_ERROR_NORMAL = 0x1,
      SERVICE_ERROR_SEVERE = 0x2,
      SERVICE_ERROR_CRITICAL = 0x3,
      msidbServiceInstallErrorControlVital = 0x8000,
      SERVICEERRORCONTROL_NO_CHANGE = SERVICE_NO_CHANGE
    }

    private enum SERVICE_STATE_REQUEST
    {
      SERVICE_ACTIVE = 0x1,
      SERVICE_INACTIVE = 0x2,
      SERVICE_STATE_ALL = (SERVICE_ACTIVE | SERVICE_INACTIVE)
    }

    private enum SERVICE_CONTROL_TYPE
    {
      SERVICE_CONTROL_STOP = 0x1,
      SERVICE_CONTROL_PAUSE = 0x2,
      SERVICE_CONTROL_CONTINUE = 0x3,
      SERVICE_CONTROL_INTERROGATE = 0x4,
      SERVICE_CONTROL_SHUTDOWN = 0x5,
      SERVICE_CONTROL_PARAMCHANGE = 0x6,
      SERVICE_CONTROL_NETBINDADD = 0x7,
      SERVICE_CONTROL_NETBINDREMOVE = 0x8,
      SERVICE_CONTROL_NETBINDENABLE = 0x9,
      SERVICE_CONTROL_NETBINDDISABLE = 0xA,
      SERVICE_CONTROL_DEVICEEVENT = 0xB,
      SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0xC,
      SERVICE_CONTROL_POWEREVENT = 0xD,
      SERVICE_CONTROL_SESSIONCHANGE = 0xE
    }

    [Flags]
    private enum SERVICE_CONTROL_ACCEPTED
    {
      SERVICE_ACCEPT_NONE = 0x0,
      SERVICE_ACCEPT_STOP = 0x1,
      SERVICE_ACCEPT_PAUSE_CONTINUE = 0x2,
      SERVICE_ACCEPT_SHUTDOWN = 0x4,
      SERVICE_ACCEPT_PARAMCHANGE = 0x8,
      SERVICE_ACCEPT_NETBINDCHANGE = 0x10,
      SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x20,
      SERVICE_ACCEPT_POWEREVENT = 0x40,
      SERVICE_ACCEPT_SESSIONCHANGE = 0x80
    }

    #endregion PInvoke declaration
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.