socketserverservice.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """
  2. A windows service wrapper for the py.execnet socketserver.
  3. To use, run:
  4. python socketserverservice.py register
  5. net start ExecNetSocketServer
  6. """
  7. import sys
  8. import win32serviceutil
  9. import win32service
  10. import win32event
  11. import win32evtlogutil
  12. import servicemanager
  13. import threading
  14. import socketserver
  15. appname = 'ExecNetSocketServer'
  16. class SocketServerService(win32serviceutil.ServiceFramework):
  17. _svc_name_ = appname
  18. _svc_display_name_ = "%s" % appname
  19. _svc_deps_ = ["EventLog"]
  20. def __init__(self, args):
  21. # The exe-file has messages for the Event Log Viewer.
  22. # Register the exe-file as event source.
  23. #
  24. # Probably it would be better if this is done at installation time,
  25. # so that it also could be removed if the service is uninstalled.
  26. # Unfortunately it cannot be done in the 'if __name__ == "__main__"'
  27. # block below, because the 'frozen' exe-file does not run this code.
  28. #
  29. win32evtlogutil.AddSourceToRegistry(self._svc_display_name_,
  30. servicemanager.__file__,
  31. "Application")
  32. win32serviceutil.ServiceFramework.__init__(self, args)
  33. self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
  34. self.WAIT_TIME = 1000 # in milliseconds
  35. def SvcStop(self):
  36. self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
  37. win32event.SetEvent(self.hWaitStop)
  38. def SvcDoRun(self):
  39. # Redirect stdout and stderr to prevent "IOError: [Errno 9]
  40. # Bad file descriptor". Windows services don't have functional
  41. # output streams.
  42. sys.stdout = sys.stderr = open('nul', 'w')
  43. # Write a 'started' event to the event log...
  44. win32evtlogutil.ReportEvent(self._svc_display_name_,
  45. servicemanager.PYS_SERVICE_STARTED,
  46. 0, # category
  47. servicemanager.EVENTLOG_INFORMATION_TYPE,
  48. (self._svc_name_, ''))
  49. print("Begin: %s" % self._svc_display_name_)
  50. hostport = ':8888'
  51. print('Starting py.execnet SocketServer on %s' % hostport)
  52. serversock = socketserver.bind_and_listen(hostport)
  53. thread = threading.Thread(
  54. target=socketserver.startserver,
  55. args=(serversock,),
  56. kwargs={'loop': True})
  57. thread.setDaemon(True)
  58. thread.start()
  59. # wait to be stopped or self.WAIT_TIME to pass
  60. while True:
  61. result = win32event.WaitForSingleObject(
  62. self.hWaitStop, self.WAIT_TIME)
  63. if result == win32event.WAIT_OBJECT_0:
  64. break
  65. # write a 'stopped' event to the event log.
  66. win32evtlogutil.ReportEvent(self._svc_display_name_,
  67. servicemanager.PYS_SERVICE_STOPPED,
  68. 0, # category
  69. servicemanager.EVENTLOG_INFORMATION_TYPE,
  70. (self._svc_name_, ''))
  71. print("End: %s" % appname)
  72. if __name__ == '__main__':
  73. # Note that this code will not be run in the 'frozen' exe-file!!!
  74. win32serviceutil.HandleCommandLine(SocketServerService)