Brian Granger wrote: > Hi, > > I have a server-like process that uses twisted. I need it to daemonize > itself and on linux/os x I am simply > using the daemonize function from twistd. This works fine. What about > Windows though....I saw that the > win32 version of twistd doesn't have (unless I am missing it) the ability to > daemonize a process. > > Is is simply impossible to daemonize a process on windows? If so, is there > any way to have a child > process on windows ignore SIGINT send to the parent? > > Cheers and thanks, > > Brian >
It is possible to daemonize a process on Windows. I experimented with adding that support to the twistd script, but got swamped with other work and couldn't finish it. Below is the code that I have so far. You can save it in a module and call the daemonize() function from your script. The process of daemonization is similar to the one on UNIX -- you have to spawn a child process twice, the first child is responsible for breaking away from any job objects (somewhat similar to becoming a session leader on UNIX), becoming a new process group leader and closing all handles (file descriptors) that might have been inherited. The second child has to open dummy std* files and a new (hidden) console, otherwise the signals stop working. There is a slight complication with window stations and desktops. Each console creates at least one window and some other user objects, so we have to create a separate desktop, or other processes would be able to manipulate them and send us arbitrary (Windows) messages. Regards, Ziga import os import sys import msvcrt import win32con import win32process import win32security import win32service from twisted.python import win32 def getPythonArgs(): """ Return the list of command line args that were used to start the current Python interpreter and were not stored in C{sys.argv}. These are the options that control the Python interpreter itself, like the Python executable, optimization level, warning filters, division behaviour and literal string handling. """ args = [sys.executable] for warnoption in sys.warnoptions: args.append("-W") args.append(warnoption) if type(1 / 2) is not int: args.append("-Qnew") if type("") is not str: args.append("-U") if not __debug__: if getPythonArgs.__doc__ is None: args.append("-OO") else: args.append("-O") return args def daemonize(): args = [os.path.abspath(__file__)] + sys.argv executable = sys.executable cmdline = win32.quoteArguments(getPythonArgs() + args) inherit = False flags = (win32process.CREATE_BREAKAWAY_FROM_JOB | # session leader win32process.CREATE_NEW_PROCESS_GROUP | # group leader win32process.DETACHED_PROCESS) # no controlling terminal info = win32process.STARTUPINFO() win32process.CreateProcess(executable, cmdline, None, None, inherit, flags, None, None, info) # Do what exec* functions do, let the OS do the cleanup. os._exit(0) def daemonize2(): args = [sys.argv[1], "--nodaemon"] + sys.argv[2:] executable = sys.executable cmdline = win32.quoteArguments(getPythonArgs() + args) inherit = True # create an invisible console flags = (win32process.CREATE_NO_WINDOW attributes = win32security.SECURITY_ATTRIBUTES() attributes.bInheritHandle = True station = win32service.CreateWindowStation(None, 0, win32con.GENERIC_READ | win32con.GENERIC_WRITE, attributes) station.SetProcessWindowStation() sname = win32service.GetUserObjectInformation(station, win32service.UOI_NAME) dname = str(os.getpid()) desktop = win32service.CreateDesktop(dname, 0, win32con.GENERIC_READ | win32con.GENERIC_WRITE, attributes) desktop.SetThreadDesktop() null = os.open("NUL", os.O_RDWR) handle = msvcrt.get_osfhandle(null) info = win32process.STARTUPINFO() info.lpDesktop = "%s\\%s" % (sname, dname) info.dwFlags = win32process.STARTF_USESTDHANDLES info.hStdInput = info.hStdOutput = info.hStdError = handle win32process.CreateProcess(executable, cmdline, None, None, inherit, flags, None, None, info) # Same as above, exit as fast as possible. os._exit(0) if __name__ == "__main__": daemonize2() _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python