55from contextlib import contextmanager
66
77from windows import utils
8+ from windows .pycompat import int_types
89import windows .generated_def as gdef
910from windows .generated_def import *
1011from windows import security
1112from windows .pycompat import basestring
1213
13- # TODO: RM :)
14- ServiceStatus = namedtuple ("ServiceStatus" , ["type" , "state" , "control_accepted" , "flags" ])
1514"""
1615``type`` might be one of:
1716
4039
4140
4241class ServiceManager (utils .AutoHandle ):
43- _close_function = staticmethod (windows .winproxy .CloseServiceHandle )
44-
4542 def _get_handle (self ):
4643 return windows .winproxy .OpenSCManagerA (dwDesiredAccess = gdef .MAXIMUM_ALLOWED )
4744
4845 def open_service (self , name , access = gdef .MAXIMUM_ALLOWED ):
4946 return windows .winproxy .OpenServiceA (self .handle , name , access ) # Check service exists :)
5047
51- def get_service (self , name , access = gdef .MAXIMUM_ALLOWED ):
52- handle = self .open_service (name , access )
53- return NewService (name = name , handle = handle )
48+ def get_service (self , key , access = gdef .MAXIMUM_ALLOWED ):
49+ if isinstance (key , int_types ):
50+ return self .enumerate_services ()[key ]
51+ if isinstance (key , slice ):
52+ # Get service list
53+ servlist = self .enumerate_services ()
54+ # Extract indexes matching the slice
55+ indexes = key .indices (len (servlist ))
56+ return [servlist [idx ] for idx in range (* indexes )]
57+ # Retrieve service by its name
58+ handle = self .open_service (key , access )
59+ return Service (name = key , handle = handle )
5460
5561 __getitem__ = get_service
5662
@@ -83,7 +89,7 @@ def _enumerate_services_generator(self):
8389 services_array = (gdef .ENUM_SERVICE_STATUS_PROCESSA * nb_services .value ).from_buffer (buffer )
8490 for service_info in services_array :
8591 shandle = self .open_service (service_info .lpServiceName )
86- yield NewService (handle = shandle , name = service_info .lpServiceName , description = service_info .lpDisplayName )
92+ yield Service (handle = shandle , name = service_info .lpServiceName , description = service_info .lpDisplayName )
8793 return
8894
8995 __iter__ = _enumerate_services_generator
@@ -92,11 +98,9 @@ def enumerate_services(self):
9298 return list (self ._enumerate_services_generator ())
9399
94100
95- class NewService (gdef .SC_HANDLE ):
96- # close_function = windows.winproxy.CloseServiceHandle
97-
101+ class Service (gdef .SC_HANDLE ):
98102 def __init__ (self , handle , name , description = None ):
99- super (NewService , self ).__init__ (handle )
103+ super (Service , self ).__init__ (handle )
100104 self .name = name
101105 """The name of the service
102106
@@ -115,12 +119,16 @@ def description(self):
115119
116120 @property
117121 def status (self ):
122+ """The status of the service
123+
124+ :type: :class:`~windows.generated_def.winstructs.SERVICE_STATUS_PROCESS`
125+ """
118126 buffer = windows .utils .BUFFER (gdef .SERVICE_STATUS_PROCESS )()
119127 size_needed = gdef .DWORD ()
120128 windows .winproxy .QueryServiceStatusEx (self , gdef .SC_STATUS_PROCESS_INFO , buffer .cast (gdef .LPBYTE ), ctypes .sizeof (buffer ), size_needed )
121129 return buffer [0 ]
122130
123- @utils . fixedpropety
131+ @property # Can change if service is started/stopped when the object exist
124132 def process (self ):
125133 """The process running the service (if any)
126134
@@ -134,6 +142,10 @@ def process(self):
134142
135143 @property
136144 def security_descriptor (self ):
145+ """The security descriptor of the service
146+
147+ :type: :class:`~windows.security.SecurityDescriptor`
148+ """
137149 return security .SecurityDescriptor .from_service (self .name )
138150
139151 def start (self , args = None ):
@@ -151,7 +163,7 @@ def stop(self):
151163 return status
152164
153165 def __repr__ (self ):
154- return """<{0} "{1}" {2}>""" .format (type (self ).__name__ , self .name , self .status .state )
166+ return """<{0} "{1}" {2!r }>""" .format (type (self ).__name__ , self .name , self .status .state )
155167
156168 def __del__ (self ):
157169 return windows .winproxy .CloseServiceHandle (self )
0 commit comments