= Description
  An interface for MS Windows Services.
    
= Prerequisites
  ffi 1.0 or later
	
  This library is only supported for the Windows NT family of operating
  systems, e.g. 2000, XP, 2003, etc. It is NOT supported (and won't
  work) for any version of DOS or Windows 95/98/ME. It is also not
  supported on NT 4, as that platform is defunct.
   
  It should work on Windows XP Home, but is not officially supported for
  that platform.
    
= Synopsis
  require "win32/service"
  include Win32
    
  # Create a new service
  Service.create(
    :service_name       => 'some_service', 
    :service_type       => Service::WIN32_OWN_PROCESS,
    :description        => 'A custom service I wrote just for fun'
    :start_type         => Service::AUTO_START,
    :error_control      => Service::ERROR_NORMAL,
    :binary_path_name   => 'C:\path\to\some_service.exe',
    :load_order_group   => 'Network',
    :dependencies       => ['W32Time','Schedule']
    :service_start_name => 'SomeDomain\\User',
    :password           => 'XXXXXXX',
    :display_name       => 'This is some service'
  )
    
  # Configure a service that already exists
  Service.configure(:display_name => "My Bar Service")
    
  Service.start("foo")
  Service.pause("foo")
  Service.resume("foo")
  Service.stop("foo")
    
  Service.delete("foo")
   
  Service.get_display_name("Schedule") # "Task Scheduler"
  Service.get_service_name("ClipBook") # "ClipSrv"
   
  Service.status('W32Time') => <struct Struct::ServiceStatus ...>
    
  # Enumerate over all services, inspecting each struct  
  Service.services{ |s|
    puts s.inspect
  }
    
= Class Methods
Service.new(options={})
  Creates a new service. The +options+ parameter is a hash that can
  contain any of the following parameters, and their default values:
   
  KEY               DEFAULT
  * service_name       => nil (mandatory)
  * host               => nil
  * display_name       => service_name
  * desired_access     => Service::ALL_ACCESS
  * service_type       => Service::WIN32_OWN_PROCESS|Service::INTERACTIVE_PROCESS
  * start_type         => Service::DEMAND_START
  * error_control      => Service::ERROR_NORMAL
  * binary_path_name   => nil
  * load_order_group   => nil
  * dependencies       => nil
  * service_start_name => nil
  * password           => nil
  * description        => nil

Service.configure(options={})   
  Configures an existing service. The +options+ parameter is a hash that can
  contain any of the following parameters:
   
  * service_name (mandatory)
  * host
  * service_type
  * start_type
  * error_control
  * binary_path_name
  * load_order_group
  * dependencies
  * service_start_name
  * password (used with service_start_name)
  * display_name
  * description
   
Service.config_info(service, host=nil)
  Returns a ServiceConfigInfo struct containing the configuration information
  about +service+ on +host+, or the local host if no host is specified.
   
Service.create
  Alias for Service.new
    
Service.delete(service, host=nil)
  Deletes the specified +service+ on +host+.  If no host is given,
  then it deletes it on the local machine.
    
Service.exists?(service)
  Returns true if the specified service exists, false otherwise.
    
Service.pause(service, host=nil)
  Pauses the specified +service+ on +host+, or the local machine if
  no host is provided.
    
Service.resume(service, host=nil)
  Resumes the specified +service+ on +host+, or the local machine if
  no host is specified.
    
Service.services(host=nil, group=nil){ |struct| ... }
  Enumerates over a list of service types on host, or the local
  machine if no host is specified, yielding a Win32Service struct for each
  service.

  If a 'group' is specified, then only those services that belong to
  that group are enumerated.  If an empty string is provided, then only
  services that do not belong to any group are enumerated. If this parameter
  is nil, group membership is ignored and all services are enumerated.
	
  The 'group' option is only available on Windows 2000 or later, and only
  if compiled with VC++ 7.0 or later, or the .NET SDK.  The Win32Service
  struct contains the following members:
	
  * service_name
  * display_name
  * service_type
  * current_state
  * controls_accepted
  * win32_exit_code
  * service_specific_exit_code
  * check_point
  * wait_hint
  * binary_path_name
  * start_type
  * error_control
  * load_order_group
  * tag_id
  * start_name
  * dependencies
  * description
  * interactive?
  * pid             (Win2k or later)
  * service_flags   (Win2k or later)
	
  Note that the 'pid' and 'service_flags' members are only available on
  Windows 2000 or later, and only if built with VC++ 7.0 or later (or the
  .NET SDK).
	
Service.start(service, host=nil, *args)
  Starts the specified +service+ on +host+, or the local machine if no
  host is specified.  Any +args+ passed here are passed as start parameters
  to the service.
   
Service.status(service)
  Returns a Win32ServiceStatus struct for the specified service (or
  raises a Win32::ServiceError if not found).  The Win32ServiceStatus
  struct contains the following members.
    
  * service_type
  * current_state
  * controls_accepted
  * win32_exit_code
  * service_specific_exit_code
  * check_point
  * wait_hint
  * interactive?
    
Service.stop(service, host=nil)
  Stops the specified +service+ on +host+, or the local machine if no
  host is specified.	
    
= Create and configure options
binary_path_name
  The binary to be used for the service. The path must be the fully
  qualified path name. A path that contains a space must be quoted so that
  it is correctly interpreted. The path may also include arguments to the
  service entry point (typically the 'main' function).

dependencies
  Any dependencies the service has in order to run. This can be a string
  or an array of strings.
   
description
  A text string describing the service.
        
display_name
  The display name to be used by user interface programs to identify the
  service. The string has a maximum length of 256 characters. Case
  sensitivity is preserved.
    
  The default is to set the display name to the same string as the
  service name.
   
error_control
  The error control for the service. The default is Service::ERROR_NORMAL.
   
  See the "Error Control Contants" section for available options and their
  meanings.
    
load_order_group
  The load order group, a string that names the load ordering group of
  which this service is a member. The default is nil.
    
password
  Sets the passsword to the account name specified in the Service#start_name
  method.  By default, this value is set to nil, which is appropriate if
  the account has no password or if the service runs in the
  'LocalService', 'NetworkService', or 'LocalSystem' account.
    
  Note that passwords are ignored for driver services.
    
service_name
  The service name for the service. This value must be set in order
  to create a service. The string has a maximum length of 256 characters.
    
service_type
  The service type for the service. The default is
  Service::WIN32_OWN_PROCESS | Service::INTERACTIVE_PROCESS.

  See the "Service Type Contants" section for available options and their
  meanings.
    
start_name
  Sets the name of the account under which the service should run.
  By default the 'LocalSystem' account is used.
    
start_type
  The start type for the service. The default is Service::DEMAND_START.
    
  See the "Start Type Contants" section for available options and their
  meanings.
    
= Constants

=== Standard Constants
VERSION
  The current version number of this package, returned as a string.
    
=== Desired Access Constants
Service::MANAGER_ALL_ACCESS
  Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights 
  in the table.
    
Service::MANAGER_CREATE_SERVICE
  Required to call the CreateService function to create a service object
  and add it to the database.
    
Service::MANAGER_CONNECT
  Required to connect to the service control manager.
    
Service::MANAGER_ENUMERATE_SERVICE
  Required to call the EnumServicesStatus function to list the services
  that are in the database.
    
Service::MANAGER_LOCK
  Required to call the LockServiceDatabase function to acquire a lock on the
  database.
    
Service::MANAGER_BOOT_CONFIG
  Required to call the NotifyBootConfigStatus() (internal) function.  Not
  defined with all compilers.
    
Service::MANAGER_QUERY_LOCK_STATUS
  Required to call the QueryServiceLockStatus() (internal) function to
  retrieve the lock status information for the database.
       
=== Service Type Constants
Service::FILE_SYSTEM_DRIVER
  File system driver service.
    
Service::KERNEL_DRIVER
  Driver service.
    
Service::WIN32_OWN_PROCESS
  Service that runs in its own process.
    
Service::WIN32_SHARE_PROCESS
  Service that shares a process with one or more other services.
    
Service::INTERACTIVE_PROCESS
  The service can interact with the desktop.  This can only be used if
  either SERVICE_WIN32_OWN_PROCESS or SERVICE_WIN32_SHARE_PROCESS is
  specified as well, and the service is running in the context of the
  LocalSystem account (which is the default for this module, btw).
    
=== Start Type Constants
Service::AUTO_START
  A service started automatically by the service control manager during
  system startup.
    
Service::BOOT_START
  A device driver started by the system loader.  This value is valid only
  for driver services.
    
Service::DEMAND_START
  A service started by the service control manager when a process calls
  the StartService() function.
    
Service::DISABLED
  A service that cannot be started.  Attempts to start the service result
  in an error.
    
Service::SYSTEM_START
  A device driver started by the IoInitSystem() function.  This value is
  valid only for driver services.
    
=== Error Control Constants
Service::ERROR_IGNORE
  The startup program logs the error but continues the startup operation.
    
Service::ERROR_NORMAL
  The startup program logs the error and puts up a message box pop-up but
  continues the startup operation.
    
Service::ERROR_SEVERE
  The startup program logs the error.  If the last-known-good configuration
  is being started, the startup operation continues.  Otherwise, the system
  is restarted with the last-known-good configuration.
   
Service::ERROR_CRITICAL
  The startup program logs the error, if possible.  If the last-known-good
  configuration is being started the startup operation fails.  Otherwise,
  the system is restarted with the last-known-good configuration.
    
= Notes
  See the MSDN API with regards to CreateService(), etc at http://www.msdn.com.
    
  Some API ideas taken (or not) from both Python's win32serviceutil.py and
  Perl's Win32::Service module.
   
  I don't truly understand how to allow a tag_id in the create_service()
  method, so for now it's set to NULL automatically. Suggestions welcome.
    
= Known Bugs
  There may be a failure in the test suite if the W32Time dependency is
  not started.

  If you find any bugs please log them on the github project page at
  https://github.com/djberg96/win32-service
   
= Acknowledgements
  Many thanks go to Patrick Hurley for providing the fix for the thread
  blocking issue in the original C code. Thanks also go to Kevin Burge for
  his patch that solved service responsiveness issues.
    
= Future Plans
  Add Tag_ID support.
  Add ability to create or modify service failure actions.
    
= Copyright
  (C) 2003-2016, Daniel J. Berger, All Rights Reserved
    
= Warranty
  This package is provided "as is" and without any express or
  implied warranties, including, without limitation, the implied
  warranties of merchantability and fitness for a particular purpose.
    
== Authors
* Daniel J. Berger   
* Park Heesob
