mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Finishing samples/python_service.py
This commit is contained in:
@@ -116,4 +116,28 @@ SERVICE_WIN32_OWN_PROCESS)
|
||||
#define SERVICE_ACCEPT_SESSIONCHANGE 0x00000080
|
||||
#define SERVICE_ACCEPT_PRESHUTDOWN 0x00000100
|
||||
#define SERVICE_ACCEPT_TIMECHANGE 0x00000200
|
||||
#define SERVICE_ACCEPT_TRIGGEREVENT 0x00000400
|
||||
#define SERVICE_ACCEPT_TRIGGEREVENT 0x00000400
|
||||
|
||||
//
|
||||
// Service object specific access type
|
||||
//
|
||||
#define SERVICE_QUERY_CONFIG 0x0001
|
||||
#define SERVICE_CHANGE_CONFIG 0x0002
|
||||
#define SERVICE_QUERY_STATUS 0x0004
|
||||
#define SERVICE_ENUMERATE_DEPENDENTS 0x0008
|
||||
#define SERVICE_START 0x0010
|
||||
#define SERVICE_STOP 0x0020
|
||||
#define SERVICE_PAUSE_CONTINUE 0x0040
|
||||
#define SERVICE_INTERROGATE 0x0080
|
||||
#define SERVICE_USER_DEFINED_CONTROL 0x0100
|
||||
|
||||
#define 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)
|
||||
@@ -922,6 +922,18 @@ Functions
|
||||
|
||||
.. function:: StartServiceCtrlDispatcherW(lpServiceStartTable)
|
||||
|
||||
.. function:: RegisterServiceCtrlHandlerExA(lpServiceName, lpHandlerProc, lpContext)
|
||||
|
||||
.. function:: RegisterServiceCtrlHandlerExW(lpServiceName, lpHandlerProc, lpContext)
|
||||
|
||||
.. function:: RegisterServiceCtrlHandlerA(lpServiceName, lpHandlerProc)
|
||||
|
||||
.. function:: RegisterServiceCtrlHandlerW(lpServiceName, lpHandlerProc)
|
||||
|
||||
.. function:: SetServiceStatus(hServiceStatus, lpServiceStatus)
|
||||
|
||||
.. function:: SetServiceBits(hServiceStatus, dwServiceBits, bSetBitsOn, bUpdateImmediately)
|
||||
|
||||
.. function:: SetupDiClassNameFromGuidA(ClassGuid, ClassName, ClassNameSize, RequiredSize)
|
||||
|
||||
.. function:: SetupDiClassNameFromGuidW(ClassGuid, ClassName, ClassNameSize, RequiredSize)
|
||||
|
||||
@@ -511,6 +511,10 @@ Simple types
|
||||
|
||||
.. autoclass:: PDNS_QUERY_COMPLETION_ROUTINE
|
||||
|
||||
.. autoclass:: LPHANDLER_FUNCTION
|
||||
|
||||
.. autoclass:: LPHANDLER_FUNCTION_EX
|
||||
|
||||
.. autoclass:: LPCONTEXT
|
||||
|
||||
.. autoclass:: HCERTSTORE
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import sys
|
||||
import os.path
|
||||
import argparse
|
||||
import datetime
|
||||
import ctypes
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
SERVICE_NAME = u"PFW_SERVICE_DEMO"
|
||||
SERVICE_DESCRIPTION = u"PythonForWindows demo service"
|
||||
|
||||
SERVICE_LOGFILE = os.path.join(os.path.dirname(__file__), "logs.txt")
|
||||
|
||||
SERVICE_HANDLE = None
|
||||
|
||||
def install_demo_service():
|
||||
path = "{executable} {pyfile} --run".format(executable=sys.executable, pyfile=__file__)
|
||||
print("Registering service <{0}> as : <{1}>".format(SERVICE_NAME, path))
|
||||
newservice = windows.system.services.create(
|
||||
name=SERVICE_NAME,
|
||||
description=SERVICE_DESCRIPTION,
|
||||
access=gdef.SERVICE_ALL_ACCESS,
|
||||
type=gdef.SERVICE_WIN32_OWN_PROCESS,
|
||||
start=gdef.SERVICE_DEMAND_START,
|
||||
path=path,
|
||||
user=None
|
||||
)
|
||||
print(newservice)
|
||||
return
|
||||
|
||||
def uninstall_demo_service():
|
||||
print("Deleting service")
|
||||
print(windows.system.services[SERVICE_NAME].delete())
|
||||
|
||||
|
||||
|
||||
def log(s):
|
||||
with open(SERVICE_LOGFILE, "a") as f:
|
||||
f.write("[{time}] {s}\n".format(time=datetime.datetime.now(), s=s))
|
||||
|
||||
|
||||
@ctypes.WINFUNCTYPE(gdef.DWORD, gdef.DWORD, gdef.DWORD, gdef.PVOID, gdef.PVOID)
|
||||
def service_handlerex(dwControl, dwEventType, lpEventData, lpContext):
|
||||
log("in service_handlerex")
|
||||
log("service_handlerex: called with {0}".format(dwControl))
|
||||
if dwControl == gdef.SERVICE_CONTROL_STOP:
|
||||
log("Stopping the service")
|
||||
running_status = gdef.SERVICE_STATUS(
|
||||
dwServiceSpecificExitCode=0,
|
||||
dwServiceType =gdef.SERVICE_WIN32_OWN_PROCESS,
|
||||
dwCurrentState=gdef.SERVICE_STOPPED,
|
||||
dwWin32ExitCode=gdef.NO_ERROR,
|
||||
dwControlsAccepted=0
|
||||
)
|
||||
try:
|
||||
windows.winproxy.SetServiceStatus(SERVICE_HANDLE, running_status)
|
||||
except Exception as e:
|
||||
log(str(e))
|
||||
return 0
|
||||
|
||||
@ctypes.WINFUNCTYPE(gdef.PVOID, gdef.DWORD, ctypes.POINTER(gdef.LPWSTR))
|
||||
def service_main(dwNumServicesArgs, lpServiceArgVectors):
|
||||
global SERVICE_HANDLE
|
||||
log("In service_main")
|
||||
log("service_main: {0}".format(dwNumServicesArgs))
|
||||
log("service_main: {0}".format(lpServiceArgVectors[0]))
|
||||
|
||||
try:
|
||||
log("Calling RegisterServiceCtrlHandlerExW")
|
||||
SERVICE_HANDLE = windows.winproxy.RegisterServiceCtrlHandlerExW(SERVICE_NAME, ctypes.cast(service_handlerex, gdef.PVOID), None)
|
||||
log("RegisterServiceCtrlHandlerExW handle: {0}".format(SERVICE_HANDLE))
|
||||
|
||||
running_status = gdef.SERVICE_STATUS(
|
||||
dwServiceSpecificExitCode=0,
|
||||
dwServiceType =gdef.SERVICE_WIN32_OWN_PROCESS,
|
||||
dwCurrentState=gdef.SERVICE_RUNNING,
|
||||
dwWin32ExitCode=gdef.NO_ERROR,
|
||||
dwControlsAccepted=gdef.SERVICE_ACCEPT_STOP | gdef.SERVICE_ACCEPT_PAUSE_CONTINUE
|
||||
)
|
||||
res = windows.winproxy.SetServiceStatus(SERVICE_HANDLE, running_status)
|
||||
log("Service is running : {0}".format(res))
|
||||
except Exception as e:
|
||||
log(str(e))
|
||||
raise
|
||||
|
||||
return None
|
||||
|
||||
def run_demo_service():
|
||||
log("start of run_demo_service()")
|
||||
try:
|
||||
SERVICE_TABLE = (gdef.SERVICE_TABLE_ENTRYW * 2)(
|
||||
gdef.SERVICE_TABLE_ENTRYW(SERVICE_NAME, ctypes.cast(service_main, gdef.PVOID)),
|
||||
gdef.SERVICE_TABLE_ENTRYW(None, None),
|
||||
)
|
||||
log("Calling: StartServiceCtrlDispatcherW()")
|
||||
result = windows.winproxy.StartServiceCtrlDispatcherW(SERVICE_TABLE)
|
||||
log("StartServiceCtrlDispatcherW returned: {0}".format(result))
|
||||
log("Quitting")
|
||||
except Exception as e:
|
||||
log(str(e))
|
||||
raise
|
||||
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(prog=__file__, formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument("--install", action="store_true", help="Install the service in registry")
|
||||
group.add_argument("--uninstall", action="store_true", help="UnInstall the service in registry")
|
||||
group.add_argument("--run", action="store_true", help="Called by the services.exe to run the service")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
if args.install:
|
||||
install_demo_service()
|
||||
elif args.uninstall:
|
||||
uninstall_demo_service()
|
||||
elif args.run:
|
||||
log("calling run_demo_service()")
|
||||
log(sys.argv)
|
||||
run_demo_service()
|
||||
else:
|
||||
raise ValueError("Unknown argument")
|
||||
@@ -149,7 +149,7 @@ class ServiceManager(utils.AutoHandle):
|
||||
def enumerate_services(self):
|
||||
return list(self._enumerate_services_generator())
|
||||
|
||||
def create(self, name, description, access, type, start, path):
|
||||
def create(self, name, description, access, type, start, path, user=None):
|
||||
newservice_handle = windows.winproxy.CreateServiceW(
|
||||
self.handle, # hSCManager
|
||||
name, # lpServiceName
|
||||
@@ -162,7 +162,7 @@ class ServiceManager(utils.AutoHandle):
|
||||
None, # lpLoadOrderGroup
|
||||
None, # lpdwTagId
|
||||
None, # lpDependencies
|
||||
None, # lpServiceStartName
|
||||
user, # lpServiceStartName
|
||||
None) # lpPassword
|
||||
|
||||
return Service(handle=newservice_handle, name=name, description=description)
|
||||
@@ -238,6 +238,9 @@ class Service(gdef.SC_HANDLE):
|
||||
windows.winproxy.ControlService(self, gdef.SERVICE_CONTROL_STOP, status)
|
||||
return status
|
||||
|
||||
def delete(self):
|
||||
return windows.winproxy.DeleteService(self)
|
||||
|
||||
def __repr__(self):
|
||||
return urepr_encode(u"""<{0} "{1}" {2!r}>""".format(type(self).__name__, self.name, self.status.state))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user