[Twisted-Python] Running twistd and tac files as Windows service

Michael Schlenker msc at contact.de
Wed Oct 24 12:14:33 EDT 2012

Am 24.10.2012 14:14, schrieb Phil Mayers:
> n 24/10/12 12:33, Michael Schlenker wrote:
>> Am 24.10.2012 11:01, schrieb Phil Mayers:
>>> On 10/24/2012 08:43 AM, John Aherne wrote:
>> But what you are talking about is the SetConsoleCtrlHandler function.
>> http://docs.activestate.com/activepython/2.4/pywin32/win32api__SetConsoleCtrlHandler_meth.html
>> http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016%28v=vs.85%29.aspx
>> Thats relevant if your process has a console, e.g. is not a GUI app.
>> (pythonw.exe vs. python.exe). If you run as a GUI app you might get a
>> WM_QUERYENDSESSION or similar message.
>> You get a CTRL_LOGOFF_EVENT when a user on the machine logs off and you
>> run as a subprocess of a service and need to ignore it. The service
>> itself should deal with this already.
> Interesting.
> I've just looked over the code we've got. It actually does something
> rather more involved than I'd first thought. Specifcally, the "ntsvc.py"
> code is pure-python, no Twisted. It actually runs the Twisted daemon as
> a sub-process, like this:
> import os
> class MyService(win32serviceutil.ServiceFramework):
>      """NT Service."""
>      _svc_name_ = "opimport-wrap"
>      _svc_display_name_ = "Marval opimport wrapper"
>      def SvcDoRun(self):
>          self.childServer = Popen([
>            "c:/python25/pythonw.exe",SCRIPT,"svc"
>          ])
>          self.childServer.wait()
this looks dubious, are you sure you can still react to ServiceManager
actions like 'Stop' or 'Query' this way, isn't this wait() blocking?

> My memory is hazy on this, but if I recall correctly the main reason it
> works this way is that I can execute the twisted script directly from
> the console (for debugging) or via the service wrapper.
> Are you suggesting that if I change that subprocess to use "python.exe"
> versus "pythonw.exe" I would not need to disable the signal handlers?

Won't probably help, not sure though.

If you ever import the 'time' module, as Python registers a control
handler there, to allow time.sleep() to wake up when ctrl-c is pressed
or the system shuts down, so i assume it has a console anyway.

from timemodule.c
    /* Helper to allow interrupts for Windows.
       If Ctrl+C event delivered while not sleeping
       it will be ignored.
    main_thread = PyThread_get_thread_ident();
    hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
#endif /* MS_WINDOWS */

The usual workaround to keep a service subprocess with a console alive
is to simply register your own ConsoleHandler to override the default
(which is ExitProcess()) and return TRUE, so the default handler doesn't

If you spawn a lot of subprocess (around 100 at a time) you will
additionally have fun with random crashes once you hit the DesktopHeap
Memory limit.


Michael Schlenker
Software Architect

CONTACT Software GmbH           Tel.:   +49 (421) 20153-80
Wiener Straße 1-3               Fax:    +49 (421) 20153-41
28359 Bremen
http://www.contact.de/          E-Mail: msc at contact.de

Sitz der Gesellschaft: Bremen
Geschäftsführer: Karl Heinz Zachries, Ralf Holtgrefe
Eingetragen im Handelsregister des Amtsgerichts Bremen unter HRB 13215

More information about the Twisted-Python mailing list