[pywin32-checkins] pywin32/win32/Lib win32serviceutil.py,1.13,1.14
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
|
From: Mark H. <mha...@us...> - 2004-09-13 02:19:27
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31688 Modified Files: win32serviceutil.py Log Message: Allow 'start' and 'stop' to wait for the service to actually start or stop. Particularly useful for installers/uninstallers, or anything that needs to know the service is looking good before continuing. Index: win32serviceutil.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32serviceutil.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** win32serviceutil.py 16 Aug 2004 12:47:34 -0000 1.13 --- win32serviceutil.py 13 Sep 2004 02:19:18 -0000 1.14 *************** *** 319,322 **** --- 319,334 ---- return retList + def WaitForServiceStatus(serviceName, status, waitSecs, machine=None): + """Waits for the service to return the specified status. You + should have already requested the service to enter that state""" + hscm = win32service.OpenSCManager(machine,None,win32service.SC_MANAGER_ALL_ACCESS) + for i in range(waitSecs*4): + now_status = QueryServiceStatus(serviceName)[1] + if now_status == status: + break + win32api.Sleep(250) + else: + raise pywintypes.error, (winerror.ERROR_SERVICE_REQUEST_TIMEOUT, "QueryServiceStatus", win32api.FormatMessage(winerror.ERROR_SERVICE_REQUEST_TIMEOUT)[:-2]) + def __StopServiceWithTimeout(hs, waitSecs = 30): try: *************** *** 437,440 **** --- 449,457 ---- print " --perfmondll file: .dll file to use when querying the service for" print " performance data, default = perfmondata.dll" + print "Options for 'start' and 'stop' commands only:" + print " --wait seconds: Wait for the service to actually start or stop." + print " If you specify --wait with the 'stop' option, the service" + print " and all dependent services will be stopped, each waiting" + print " the specified period." sys.exit(1) *************** *** 460,478 **** serviceClassString = GetServiceClassString(cls) ! # First we process all arguments which require access to the ! # arg list directly ! if argv[1]=="start": print "Starting service %s" % (serviceName) try: ! StartService(serviceName, argv[2:]) except win32service.error, (hr, fn, msg): print "Error starting service: %s" % msg ! elif argv[1]=="restart": print "Restarting service %s" % (serviceName) ! RestartService(serviceName, argv[2:]) ! elif argv[1]=="debug": ! svcArgs = string.join(sys.argv[2:]) exeName = LocateSpecificServiceExe(serviceName) try: --- 477,540 ---- serviceClassString = GetServiceClassString(cls) ! # Pull apart the command line ! import getopt ! try: ! opts, args = getopt.getopt(argv[1:], customInstallOptions,["password=","username=","startup=","perfmonini=", "perfmondll=", "interactive", "wait="]) ! except getopt.error, details: ! print details ! usage() ! userName = None ! password = None ! perfMonIni = perfMonDll = None ! startup = None ! interactive = None ! waitSecs = 0 ! for opt, val in opts: ! if opt=='--username': ! userName = val ! elif opt=='--password': ! password = val ! elif opt=='--perfmonini': ! perfMonIni = val ! elif opt=='--perfmondll': ! perfMonDll = val ! elif opt=='--interactive': ! interactive = 1 ! elif opt=='--startup': ! map = {"manual": win32service.SERVICE_DEMAND_START, "auto" : win32service.SERVICE_AUTO_START, "disabled": win32service.SERVICE_DISABLED} ! try: ! startup = map[string.lower(val)] ! except KeyError: ! print "'%s' is not a valid startup option" % val ! elif opt=='--wait': ! try: ! waitSecs = int(val) ! except ValueError: ! print "--wait must specify an integer number of seconds." ! usage() ! ! arg=args[0] ! knownArg = 0 ! # First we process all arguments which pass additional args on ! if arg=="start": ! knownArg = 1 print "Starting service %s" % (serviceName) try: ! StartService(serviceName, args[1:]) ! if waitSecs: ! WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs) except win32service.error, (hr, fn, msg): print "Error starting service: %s" % msg ! elif arg=="restart": ! knownArg = 1 print "Restarting service %s" % (serviceName) ! RestartService(serviceName, args[1:]) ! if waitSecs: ! WaitForServiceStatus(serviceName, win32service.SERVICE_RUNNING, waitSecs) ! elif arg=="debug": ! knownArg = 1 ! svcArgs = string.join(args[1:]) exeName = LocateSpecificServiceExe(serviceName) try: *************** *** 482,605 **** except KeyboardInterrupt: pass - else: - # Pull apart the command line - import getopt - try: - opts, args = getopt.getopt(argv[1:], customInstallOptions,["password=","username=","startup=","perfmonini=", "perfmondll=", "interactive"]) - except getopt.error, details: - print details - usage() - userName = None - password = None - perfMonIni = perfMonDll = None - startup = None - interactive = None - for opt, val in opts: - if opt=='--username': - userName = val - elif opt=='--password': - password = val - elif opt=='--perfmonini': - perfMonIni = val - elif opt=='--perfmondll': - perfMonDll = val - elif opt=='--interactive': - interactive = 1 - elif opt=='--startup': - map = {"manual": win32service.SERVICE_DEMAND_START, "auto" : win32service.SERVICE_AUTO_START, "disabled": win32service.SERVICE_DISABLED} - try: - startup = map[string.lower(val)] - except KeyError: - print "'%s' is not a valid startup option" % val - if len(args)<>1: - usage() - arg=args[0] - knownArg = 0 - if arg=="install": - knownArg = 1 - try: - serviceDeps = cls._svc_deps_ - except AttributeError: - serviceDeps = None - try: - exeName = cls._exe_name_ - except AttributeError: - exeName = None # Default to PythonService.exe - try: - exeArgs = cls._exe_args_ - except AttributeError: - exeArgs = None - print "Installing service %s to Python class %s" % (serviceName,serviceClassString) - # Note that we install the service before calling the custom option - # handler, so if the custom handler fails, we have an installed service (from NT's POV) - # but is unlikely to work, as the Python code controlling it failed. Therefore - # we remove the service if the first bit works, but the second doesnt! - try: - InstallService(serviceClassString, serviceName, serviceDisplayName, serviceDeps = serviceDeps, startType=startup, bRunInteractive=interactive, userName=userName,password=password, exeName=exeName, perfMonIni=perfMonIni,perfMonDll=perfMonDll,exeArgs=exeArgs) - if customOptionHandler: - apply( customOptionHandler, (opts,) ) - print "Service installed" - except win32service.error, (hr, fn, msg): - if hr==winerror.ERROR_SERVICE_EXISTS: - arg = "update" # Fall through to the "update" param! - else: - print "Error installing service: %s (%d)" % (msg, hr) - err = hr - except ValueError, msg: # Can be raised by custom option handler. - print "Error installing service: %s" % str(msg) - err = -1 - # xxx - maybe I should remove after _any_ failed install - however, - # xxx - it may be useful to help debug to leave the service as it failed. - # xxx - We really _must_ remove as per the comments above... - # As we failed here, remove the service, so the next installation - # attempt works. - try: - RemoveService(serviceName) - except win32api.error: - print "Warning - could not remove the partially installed service." ! if arg == "update": ! knownArg = 1 ! try: ! serviceDeps = cls._svc_deps_ ! except AttributeError: ! serviceDeps = None ! try: ! exeName = cls._exe_name_ ! except AttributeError: ! exeName = None # Default to PythonService.exe ! try: ! exeArgs = cls._exe_args_ ! except AttributeError: ! exeArgs = None ! print "Changing service configuration" ! try: ! ChangeServiceConfig(serviceClassString, serviceName, serviceDeps = serviceDeps, startType=startup, bRunInteractive=interactive, userName=userName,password=password, exeName=exeName, displayName = serviceDisplayName, perfMonIni=perfMonIni,perfMonDll=perfMonDll,exeArgs=exeArgs) ! print "Service updated" ! except win32service.error, (hr, fn, msg): ! print "Error changing service configuration: %s (%d)" % (msg,hr) ! err = hr ! elif arg=="remove": ! knownArg = 1 ! print "Removing service %s" % (serviceName) ! try: ! RemoveService(serviceName) ! print "Service removed" ! except win32service.error, (hr, fn, msg): ! print "Error removing service: %s (%d)" % (msg,hr) err = hr ! elif arg=="stop": ! knownArg = 1 ! print "Stopping service %s" % (serviceName) try: StopService(serviceName) ! except win32service.error, (hr, fn, msg): ! print "Error stopping service: %s (%d)" % (msg,hr) ! err = hr ! if not knownArg: ! err = -1 ! print "Unknown command - '%s'" % arg ! usage() return err --- 544,640 ---- except KeyboardInterrupt: pass ! if len(args)<>1: ! usage() ! if arg=="install": ! knownArg = 1 ! try: ! serviceDeps = cls._svc_deps_ ! except AttributeError: ! serviceDeps = None ! try: ! exeName = cls._exe_name_ ! except AttributeError: ! exeName = None # Default to PythonService.exe ! try: ! exeArgs = cls._exe_args_ ! except AttributeError: ! exeArgs = None ! print "Installing service %s to Python class %s" % (serviceName,serviceClassString) ! # Note that we install the service before calling the custom option ! # handler, so if the custom handler fails, we have an installed service (from NT's POV) ! # but is unlikely to work, as the Python code controlling it failed. Therefore ! # we remove the service if the first bit works, but the second doesnt! ! try: ! InstallService(serviceClassString, serviceName, serviceDisplayName, serviceDeps = serviceDeps, startType=startup, bRunInteractive=interactive, userName=userName,password=password, exeName=exeName, perfMonIni=perfMonIni,perfMonDll=perfMonDll,exeArgs=exeArgs) ! if customOptionHandler: ! apply( customOptionHandler, (opts,) ) ! print "Service installed" ! except win32service.error, (hr, fn, msg): ! if hr==winerror.ERROR_SERVICE_EXISTS: ! arg = "update" # Fall through to the "update" param! ! else: ! print "Error installing service: %s (%d)" % (msg, hr) err = hr ! except ValueError, msg: # Can be raised by custom option handler. ! print "Error installing service: %s" % str(msg) ! err = -1 ! # xxx - maybe I should remove after _any_ failed install - however, ! # xxx - it may be useful to help debug to leave the service as it failed. ! # xxx - We really _must_ remove as per the comments above... ! # As we failed here, remove the service, so the next installation ! # attempt works. try: + RemoveService(serviceName) + except win32api.error: + print "Warning - could not remove the partially installed service." + + if arg == "update": + knownArg = 1 + try: + serviceDeps = cls._svc_deps_ + except AttributeError: + serviceDeps = None + try: + exeName = cls._exe_name_ + except AttributeError: + exeName = None # Default to PythonService.exe + try: + exeArgs = cls._exe_args_ + except AttributeError: + exeArgs = None + print "Changing service configuration" + try: + ChangeServiceConfig(serviceClassString, serviceName, serviceDeps = serviceDeps, startType=startup, bRunInteractive=interactive, userName=userName,password=password, exeName=exeName, displayName = serviceDisplayName, perfMonIni=perfMonIni,perfMonDll=perfMonDll,exeArgs=exeArgs) + print "Service updated" + except win32service.error, (hr, fn, msg): + print "Error changing service configuration: %s (%d)" % (msg,hr) + err = hr + + elif arg=="remove": + knownArg = 1 + print "Removing service %s" % (serviceName) + try: + RemoveService(serviceName) + print "Service removed" + except win32service.error, (hr, fn, msg): + print "Error removing service: %s (%d)" % (msg,hr) + err = hr + elif arg=="stop": + knownArg = 1 + print "Stopping service %s" % (serviceName) + try: + if waitSecs: + StopServiceWithDeps(serviceName, waitSecs = waitSecs) + else: StopService(serviceName) ! except win32service.error, (hr, fn, msg): ! print "Error stopping service: %s (%d)" % (msg,hr) ! err = hr ! if not knownArg: ! err = -1 ! print "Unknown command - '%s'" % arg ! usage() return err |