win32service (wxpython) -- i cannot install service

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • kkt49

    #1

    win32service (wxpython) -- i cannot install service

    # vim: et sw=4 ts=8 sts

    from wxPython.wx import *
    import sys, os, time
    import pywintypes
    import win32serviceuti l
    import win32service
    import win32event
    import win32process

    ID_ABOUT = 101
    ID_EXIT = 102

    # the max seconds we're allowed to spend backing off
    BACKOFF_MAX = 300
    # if the process runs successfully for more than BACKOFF_CLEAR_T IME
    # seconds, we reset the backoff stats to their initial values
    BACKOFF_CLEAR_T IME = 30
    # the initial backoff interval (the amount of time we wait to restart
    # a dead process)
    BACKOFF_INITIAL _INTERVAL = 5

    class Service(win32se rviceutil.Servi ceFramework):
    """ A class representing a Windows NT service that can manage an
    instance-home-based Zope/ZEO/ZRS processes """

    # The comment below is mostly irrelevant if you're running a
    standalone
    # SchoolBell server, I think. -TEH

    # The PythonService model requires that an actual on-disk class
    declaration
    # represent a single service. Thus, the below definition of
    start_cmd,
    # must be overridden in a subclass in a file within the instance
    home for
    # each instance. The below-defined start_cmd (and
    _svc_display_na me_
    # and _svc_name_) are just examples.

    # To use this script with SchoolTool, just replace "SchoolBell "
    # with "SchoolTool " in the variables below.
    # You'll also need to change 'Python24' to 'Python23' if that's
    # what you've got. -TEH

    #cmd_str = os.environ["moin_servi ce"]

    #_svc_name_ = r'moin_service'
    #_svc_display_n ame_ = r'moin_service'
    #start_cmd = r"c:\mmde\moin. exe"
    info = ['', '', '']

    def __init__(self):
    self._svc_name = info[0]
    self._svc_displ ay_name_ = info[1]
    self.start_cmd = info[2]

    win32serviceuti l.ServiceFramew ork.__init__(se lf)

    # Create an event which we will use to wait on.
    # The "service stop" request will set this event.
    self.hWaitStop = win32event.Crea teEvent(None, 0, 0, None)
    self.redirectOu tput()

    def __init__(self, args):
    self._svc_name = info[0]
    self._svc_displ ay_name_ = info[1]
    self.start_cmd = info[2]

    win32serviceuti l.ServiceFramew ork.__init__(se lf, args)
    # Create an event which we will use to wait on.
    # The "service stop" request will set this event.
    self.hWaitStop = win32event.Crea teEvent(None, 0, 0, None)
    self.redirectOu tput()

    def redirectOutput( self):
    #pass
    sys.stdout.clos e()
    sys.stderr.clos e()
    sys.stdout = NullOutput()
    sys.stderr = NullOutput()

    def SvcStop(self):
    # Before we do anything, tell the SCM we are starting the stop
    process.
    self.ReportServ iceStatus(win32 service.SERVICE _STOP_PENDING)

    # TODO: This TerminateProces s call doesn't make much sense:
    it's
    # doing a hard kill _first_, never giving the process a chance
    to
    # shut down cleanly. Compare to current Zope2 service code,
    which
    # uses Windows events to give the process a chance to shut down
    # cleanly, doing a hard kill only if that doesn't succeed.

    # stop the process if necessary
    try:
    win32process.Te rminateProcess( self.hZope, 0)
    except pywintypes.erro r:
    # the process may already have been terminated
    pass
    # And set my event.
    win32event.SetE vent(self.hWait Stop)

    # SvcStop only gets triggered when the user explictly stops (or
    restarts)
    # the service. To shut the service down cleanly when Windows is
    shutting
    # down, we also need to hook SvcShutdown.
    SvcShutdown = SvcStop

    def createProcess(s elf, cmd):
    return win32process.Cr eateProcess(
    None, cmd, None, None, 0, 0, None, None,
    win32process.ST ARTUPINFO())

    def SvcDoRun(self):
    # indicate to Zope that the process is daemon managed
    (restartable)
    # os.environ['ZMANAGED'] = '1'

    # daemon behavior: we want to to restart the process if it
    # dies, but if it dies too many times, we need to give up.

    # we use a simple backoff algorithm to determine whether
    # we should try to restart a dead process: for each
    # time the process dies unexpectedly, we wait some number of
    # seconds to restart it, as determined by the backoff interval,
    # which doubles each time the process dies. if we exceed
    # BACKOFF_MAX seconds in cumulative backoff time, we give up.
    # at any time if we successfully run the process for more thab
    # BACKOFF_CLEAR_T IME seconds, the backoff stats are reset.

    # the initial number of seconds between process start attempts
    backoff_interva l = BACKOFF_INITIAL _INTERVAL
    # the cumulative backoff seconds counter
    backoff_cumulat ive = 0

    import servicemanager

    # log a service started message
    servicemanager. LogMsg(
    servicemanager. EVENTLOG_INFORM ATION_TYPE,
    servicemanager. PYS_SERVICE_STA RTED,
    (self._svc_name _, ' (%s)' % self._svc_displ ay_name_))

    while 1:
    start_time = time.time()
    info = self.createProc ess(self.start_ cmd)
    self.hZope = info[0] # the pid
    if backoff_interva l BACKOFF_INITIAL _INTERVAL:
    # if we're in a backoff state, log a message about
    # starting a new process
    servicemanager. LogInfoMsg(
    '%s (%s): recovering from died process, new process
    '
    'started' % (self._svc_name _,
    self._svc_displ ay_name_)
    )
    rc = win32event.Wait ForMultipleObje cts(
    (self.hWaitStop , self.hZope), 0, win32event.INFI NITE)
    if rc == win32event.WAIT _OBJECT_0:
    # user sent a stop service request
    self.SvcStop()
    break
    else:
    # user did not send a service stop request, but
    # the process died; this may be an error condition
    status = win32process.Ge tExitCodeProces s(self.hZope)
    if status == 0:
    # the user shut the process down from the web
    # interface (or it otherwise exited cleanly)
    break
    else:
    # this was an abormal shutdown. if we can, we want
    to
    # restart the process but if it seems hopeless,
    # don't restart an infinite number of times.
    if backoff_cumulat ive BACKOFF_MAX:
    # it's hopeless
    servicemanager. LogErrorMsg(
    '%s (%s): process could not be restarted due
    to max '
    'restart attempts exceeded' % (
    self._svc_displ ay_name_, self._svc_name_
    ))
    self.SvcStop()
    break
    servicemanager. LogWarningMsg(
    '%s (%s): process died unexpectedly. Will
    attempt '
    'restart after %s seconds.' % (
    self._svc_name_ , self._svc_displ ay_name_,
    backoff_interva l
    )
    )
    # if BACKOFF_CLEAR_T IME seconds have elapsed since
    we last
    # started the process, reset the backoff interval
    # and the cumulative backoff time to their original
    # states
    if time.time() - start_time BACKOFF_CLEAR_T IME:
    backoff_interva l = BACKOFF_INITIAL _INTERVAL
    backoff_cumulat ive = 0
    # we sleep for the backoff interval. since this is
    async
    # code, it would be better done by sending and
    # catching a timed event (a service
    # stop request will need to wait for us to stop
    sleeping),
    # but this works well enough for me.
    time.sleep(back off_interval)
    # update backoff_cumulat ive with the time we spent
    # backing off.
    backoff_cumulat ive = backoff_cumulat ive +
    backoff_interva l
    # bump the backoff interval up by 2* the last
    interval
    backoff_interva l = backoff_interva l * 2

    # loop and try to restart the process

    # log a service stopped message
    servicemanager. LogMsg(
    servicemanager. EVENTLOG_INFORM ATION_TYPE,
    servicemanager. PYS_SERVICE_STO PPED,
    (self._svc_name _, ' (%s) ' % self._svc_displ ay_name_))

    class NullOutput:
    """A stdout / stderr replacement that discards everything."""

    def noop(self, *args, **kw):
    pass

    write = writelines = close = seek = flush = truncate = noop

    def __iter__(self):
    return self

    def next(self):
    raise StopIteration

    def isatty(self):
    return False

    def tell(self):
    return 0

    def read(self, *args, **kw):
    return ''

    readline = read

    def readlines(self, *args, **kw):
    return []


    class MyFrame(wxFrame ):
    def __init__(self, parent, ID, title):
    wxFrame.__init_ _(self, parent, ID, title, wxDefaultPositi on,
    wxSize(200, 150))
    self.CreateStat usBar()
    self.SetStatusT ext("This is the statusbar")

    menu = wxMenu()
    menu.Append(ID_ ABOUT, "&About", "More information about this
    program")
    menu.AppendSepa rator()
    menu.Append(ID_ EXIT, "E&xit", "Terminate the program")

    menuBar = wxMenuBar()
    menuBar.Append( menu, "&File");

    self.SetMenuBar (menuBar)

    # 서비스명
    servicenameText = wxStaticText(se lf, -1, "Service Name")
    self.servicenam eCtrl = wxTextCtrl(self , -1, size=(200, -1))
    # 서비스로 실행할 명령
    cmdText = wxStaticText(se lf, -1, "Service command")
    self.cmdCtrl = wxTextCtrl(self , -1, size=(200, -1))
    # 실행 버튼
    installButton = wxButton(self, -1, label="Install" , size=(80,
    -1))
    removeButton = wxButton(self, -1, label="Remove", size=(80,
    -1))
    startButton = wxButton(self, -1, label="Start", size=(80, -1))
    stopButton = wxButton(self, -1, label="Stop", size=(80, -1))
    installButton.B ind(EVT_BUTTON, self.onInstallB uttonClick)
    removeButton.Bi nd(EVT_BUTTON, self.onRemoveBu ttonClick)
    startButton.Bin d(EVT_BUTTON, self.onStartBut tonClick)
    stopButton.Bind (EVT_BUTTON, self.onStopButt onClick)

    # Sizer 구성
    sizer = wxFlexGridSizer (rows=2, cols=2, hgap=10, vgap=5)
    sizer.Add(servi cenameText) # (0, 0)
    sizer.Add(self. servicenameCtrl ) # (0, 1)
    sizer.Add(cmdTe xt) # (1, 0)
    sizer.Add(self. cmdCtrl) # (1, 1)
    sizer.Add(insta llButton) # (2, 0)
    sizer.Add(remov eButton) # (2, 1)
    sizer.Add(start Button) # (3, 0)
    sizer.Add(stopB utton) # (3, 1)

    border = wxBoxSizer()
    border.Add(size r, 0, wxALL, 10)
    self.SetSizerAn dFit(border)
    self.Fit()

    def onInstallButton Click(self, event):
    Service.info[0] = self.servicenam eCtrl.GetValue( )
    Service.info[1] = self.servicenam eCtrl.GetValue( )
    Service.info[2] = self.cmdCtrl.Ge tValue()

    #Service._svc_n ame_ = self.servicenam eCtrl.GetValue( )
    #Service._svc_d isplay_name_ = self.servicenam eCtrl.GetValue( )
    #Service.start_ cmd = self.cmdCtrl.Ge tValue()

    #win32serviceut il.HandleComman dLine(Service)
    win32serviceuti l.InstallServic e(
    win32serviceuti l.GetServiceCla ssString(Servic e),
    self.servicenam eCtrl.GetValue( ),
    self.servicenam eCtrl.GetValue( )
    )


    def onRemoveButtonC lick(self, event):
    win32serviceuti l.RemoveService (self.servicena meCtrl.GetValue ())

    def onStartButtonCl ick(self, event):
    win32serviceuti l.StartService( self.servicenam eCtrl.GetValue( ))

    def onStopButtonCli ck(self, event):
    win32serviceuti l.StopService(s elf.servicename Ctrl.GetValue() )

    #def onOkButtonClick (self, event):
    # Service._svc_na me_ = self.servicenam eCtrl.GetValue( )
    # Service._svc_di splay_name_ = self.servicenam eCtrl.GetValue( )
    # Service.start_c md = (self.cmdCtrl.G etValue())
    # sys.argv.append (self.argsCtrl. GetValue())
    # win32serviceuti l.HandleCommand Line(Service)


    class MyApp(wxApp):
    def OnInit(self):
    frame = MyFrame(NULL, -1, "Hello from wxPython")
    frame.servicena meCtrl.SetValue (r"moin_service ")
    frame.cmdCtrl.S etValue(r"c:\mm de\moin.exe")
    #frame.argsCtrl .SetValue("stop ")
    Service.info[0] =
    frame.servicena meCtrl.SetValue (r"moin_service ")
    Service.info[1] =
    frame.servicena meCtrl.SetValue (r"moin_service ")
    Service.info[2] = frame.cmdCtrl.S etValue(r"c:\mm de\moin.exe")


    frame.Show(true )
    self.SetTopWind ow(frame)
    return true

    if __name__ == '__main__':
    app = MyApp(0)
    app.MainLoop()

    ----------------------------
    start stop remove ==ok
    I cann't install service

    help!!!

  • Larry Bates

    #2
    Re: win32service (wxpython) -- i cannot install service

    I believe you misunderstand services. They don't
    have user interfaces (UIs) like other programs.
    They run without any UI as background processes that
    are in basically in an infinite loop but with a way
    to break out of the loop (stop service). If you wish
    to have a background service that has some sort of
    control UI, you need to write it as two parts. The
    service and a UI that communicates with the service
    either through a shared file, pipe, or socket server/
    client interface.

    You should pick up a copy of Python Programming on
    Win32 which is an excellent reference book for writing
    Windows services.

    -Larry Bates

    Comment

    • kkt49

      #3
      Re: win32service (wxpython) -- i cannot install service

      under code service install =ok

      _svc_name_ = r'moin_service'
      _svc_display_na me_ = r'moin_service'
      start_cmd = r"c:\mmde\moin. exe"
      #info = ['', '', '']

      def __init__(self):
      #self._svc_name = info[0]
      #self._svc_disp lay_name_ = info[1]
      #self.start_cmd = info[2]

      but, i want dynamic _svc_name_ and start_cmd


      Larry Bates 작성:
      I believe you misunderstand services. They don't
      have user interfaces (UIs) like other programs.
      They run without any UI as background processes that
      are in basically in an infinite loop but with a way
      to break out of the loop (stop service). If you wish
      to have a background service that has some sort of
      control UI, you need to write it as two parts. The
      service and a UI that communicates with the service
      either through a shared file, pipe, or socket server/
      client interface.
      >
      You should pick up a copy of Python Programming on
      Win32 which is an excellent reference book for writing
      Windows services.

      -Larry Bates

      Comment

      • Larry Bates

        #4
        Re: win32service (wxpython) -- i cannot install service

        kkt49 wrote:
        under code service install =ok
        >
        _svc_name_ = r'moin_service'
        _svc_display_na me_ = r'moin_service'
        start_cmd = r"c:\mmde\moin. exe"
        #info = ['', '', '']
        >
        def __init__(self):
        #self._svc_name = info[0]
        #self._svc_disp lay_name_ = info[1]
        #self.start_cmd = info[2]
        >
        but, i want dynamic _svc_name_ and start_cmd
        Services aren't dynamic in nature. They are static, are
        given names (that are used to start, stop, etc.) and get
        installed into servicemanager on Windows workstation or
        server. Their behavior could be dynamic, that is you could
        change what they do by communicating with them via external
        means.

        I think you better back up and tell us what you are trying
        to do at a higher level. Perhaps we can help more.

        -Larry

        Comment

        • Larry Bates

          #5
          Re: win32service (wxpython) -- i cannot install service

          Larry Bates wrote:
          kkt49 wrote:
          >under code service install =ok
          >>
          > _svc_name_ = r'moin_service'
          > _svc_display_na me_ = r'moin_service'
          > start_cmd = r"c:\mmde\moin. exe"
          > #info = ['', '', '']
          >>
          > def __init__(self):
          > #self._svc_name = info[0]
          > #self._svc_disp lay_name_ = info[1]
          > #self.start_cmd = info[2]
          >>
          >but, i want dynamic _svc_name_ and start_cmd
          >
          Services aren't dynamic in nature. They are static, are
          given names (that are used to start, stop, etc.) and get
          installed into servicemanager on Windows workstation or
          server. Their behavior could be dynamic, that is you could
          change what they do by communicating with them via external
          means.
          >
          I think you better back up and tell us what you are trying
          to do at a higher level. Perhaps we can help more.
          >
          -Larry
          Sorry, after I clicked send I "think" I understand what you
          want. You can't make a .EXE program run as a service by
          starting it as a service. If thats not what you are trying
          to do, give us some more high-level info about what it is
          that you are trying to accomplish.

          -Larry

          Comment

          Working...