Hey, Thanks for your response Dan! More examples are always needed. However, i think there is a miscommunication. That sample code you wrote is using the pywin32 code to write a windows service. This isn't what I was using, but I might have to use that if i can't get the other method (i'll explain below) to work. Were you able to get that script to compile as a cx_freeze exe? Whatever method I use, i need to have it be frozen as an EXE as python is not guaranteed to be installed on the computers that this service will be running on, and all the examples i've seen that use pywin32 seem to be assuming that python is installed.
***TLDR AT END OF MESSAGE**** ANYWAY, the method I WAS using is actually built into cx_freeze. You would never know its there, because its basically hidden in the source code, and even if you compile it yourself, you need another dependency that it never mentions (unless you look into the source code) or else it won't compile it (you need Cx_logging, and it needs to be in the parent folder of cx_freeze or else it won't find it, very annoying to figure out !). You can see the 'example' code for the win32 service in the cx_freeze repo: https://bitbucket.org/anthony_tuininga/cx_freeze/src/1282b6b6ee63/cx_Freeze/samples/service/?at=default <https://bitbucket.org/anthony_tuininga/cx_freeze/src/1282b6b6ee63/cx_Freeze/samples/service/?at=default> and the win32service.c base that cx_freeze uses (basically a windows program that embeds python, and registers a "Session Changed" function, that basically calls 1 of 3 python functions, Initialize(), Run(), and Stop() in your python code: https://bitbucket.org/anthony_tuininga/cx_freeze/src/1282b6b6ee637738210113dd88c3c198d475340f/source/bases/Win32Service.c?at=default <https://bitbucket.org/anthony_tuininga/cx_freeze/src/1282b6b6ee637738210113dd88c3c198d475340f/source/bases/Win32Service.c?at=default> I honestly like the cx_freeze method better, as its simpler, and this windows service is so stupidly simple that I didn't want to take the time to figure out the pywin32 method. All my service needs to do is to start a python process, and then when the service stops (windows shuts down, logs off), it sends a CTRL_BREAK signal to the child python process to signal that it needs to exit gracefully. The code I've written so far is posted here, you need cx_freeze with cx_logging and the win32service.c file compiled with the cx_freeze build: (using python 3 / asyncio) https://gist.github.com/mgrandi/aa70c902fa7e2215a228 <https://gist.github.com/mgrandi/aa70c902fa7e2215a228> It looks complicated, mainly because i'm using asyncio, and the python code in service.py gets called from multiple threads, but the general explanation: * Initialize() is called * Run() is called, tells the asyncio event loop to run 'do_loop()' until it finishes. ---- do_loop() runs, which creates a new process, as a NEW PROCESS GROUP (IMPORTANT), then waits on it to exit. * <time passes> * Someone hits "stop" in the windows service manager, or the computer is shutting down, whatever, the windows service stuff tells the service to stop, which in turn calls Stop() in python code, which is on a different thread then what Run() is currently running on ----Stop() tells the event loop (that is running on the main python thread, asyncio event loops are specific to the thread they are started on), to call 'stop_loop()' soon on its thread, and then Stop() returns -------- stop_loop() runs, is running on the same thread as Run() and do_loop(), sends the CTRL_BREAK signal to the process that do_loop() is waiting for to exit. The child process _should_ exit, and then stop_loop() then waits on an event. -------- run_loop() then sees the process exits, and then 'sets' the event, and then returns. Then stop_loop() sees that the event is now set, and then it tells the event loop to stop. -------- back in Run(), now that the loop is stopped, loop.run_until_complete() (or run_forever(), tried both combinations) now stops blocking and Run() finishes, and returns. * now that Run() has exited, i'm assuming the cx_freeze win32service.c wrapper tells the windows service stuff that the process is now stopped, and then the actual service EXE exits Now that you have read all that (haha), if you see in service.py, i have a dummy class TestThread, which i use to 'test' this, as you mentioned yourself that its almost impossible to really debug windows services as its an EXE, but its treated like a DLL almost. To test it in just python, i just uncomment lines 51-52 in service.py, and then just run in the python interactive shell "import service; x=service.Handle(); x.Initialize("something"); x.Run()", and then the same code runs, and then the thread will manually call the Stop() method after 20 seconds. *****TLDR HERE***** The log of this running (in the interactive shell) is here: (service.py log is the actual windows service, catcher_async.py is the 'childprocess' that is waiting for CTRL_BREAK). https://gist.github.com/mgrandi/9a168e1ef537e8052a33 <https://gist.github.com/mgrandi/9a168e1ef537e8052a33> Yes i know the logs don't match up exactly, i have a lot of them, but even though the times/pids don't match its the same output) but when i run it as a cx_freeze frozen windows service, and i register it, start it, wait a few seconds then stop it, i get this: https://gist.github.com/mgrandi/b064d99ddb28c73d398c <https://gist.github.com/mgrandi/b064d99ddb28c73d398c> Note that in the service.py log, there is the line "root|send_signal|13996: HEY GIRL ABOUT TO SEND SIGNAL DAWG", that is a logging statement i put in subprocess.py (the python module subprocess), to further debug where its failing, because as you can see in the service.py log, i'm getting a completely bogus python stack trace. If I comment out the line it says threw the exception (logging.info("SENT THE SIGNAL DAWG"), a statement i put in subprocess.py after the os.kill() call, again debugging stuff), then it will say some other random line caused the WinError, and again and again. Obviously something is going wrong with calling os.kill() when this script is running in the cx_freeze win32service.c wrapper, but i have no idea what as the stack trace is bogus, and its probably a problem in the C code anyway so a python stack trace wouldn't help anyway. "[WinError 6] The handle is invalid" is basically a python wrapped Win32 error code , and since those are vague as all heck intentionally, i have no idea which handle it is, or why its invalid, etc. If i could get the source to the generated exe that cx_freeze generates somehow then i could run it in visual studio and debug it further, but I can't figure out how to do that. So I know this is long, but I've spent way too much time for something that should be relatively simple. I'm either going to have to use pywin32 (if i can get that to compile as an exe) or just start a detached process and then check every X minutes to see if its still running. Any help would be greatly appreciated. ~Mark > On Feb 19, 2015, at 11:39 AM, Dan McCombs <dmcco...@dyn.com> wrote: > > Hi Mark, > > You are absolutely right about the lack of documentation on this, it was a > big pain in a project I worked on last year. I should probably put a blog > post together somewhere... > > I don't have a lot of time at the moment, but I took a couple of minutes to > strip down some of my code to just the basic parts for a Windows service. I > haven't actually tried using this stand alone, but it should give you a > better idea of what's entailed to get it working and hopefully answer some > questions. My biggest issue with getting this working is it was very hard to > get any kind of real debugging output in the case where the service just > wouldn't start for some reason. > > https://gist.github.com/dmccombs/49f2f0de3c3f9bd452f2 > <https://gist.github.com/dmccombs/49f2f0de3c3f9bd452f2> > > Hopefully this can help point you in the right direction, and if you have > more specific questions after playing with this I'll try to answer them. > > Take care, > > -Dan > > <http://dyn.com/> <http://twitter.com/dyn> > <http://twitter.com/dyninc> <http://facebook.com/dyn> > <http://linkedin.com/company/dyn> > Dan McCombs / Senior Software Engineer > 603 296 1568 @danmccombs <http://twitter.com/danmccombs/> > > > On Wed, Feb 18, 2015 at 11:16 PM, Mark Grandi <markgra...@gmail.com > <mailto:markgra...@gmail.com>> wrote: > I have some questions about using cx_freeze to create a python windows > service. Since there is literally 0 documentation about this, I had to look > at the source for a lot of things, but I still have some questions. I am > running python3 64 bit if it helps. > > 1: What is the lifecycle of the windows service? Obviously the first things > that get called are Initialize() and Run(), but what happens after that? I > know Run() keeps going, but mainly, what should be the last method to return? > Should Run() exit before Stop()? Its unclear from Win32Service.c what is > supposed to exit first. > > 2: Is there any way to get the 'generated source' for the exe? I'm having > problems with my program and it seems to only happen when its compiled as an > exe, (getting a WinError: Invalid Handle with a bogus stack trace) so i'm > thinking its something in the C part of the exe, but I can't really debug it > as I don't have the source to have visual studio step through / set > breakpoints. Or should I make a separate message about this problem? > > ~Mark Grandi > > ------------------------------------------------------------------------------ > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server > from Actuate! Instantly Supercharge Your Business Reports and Dashboards > with Interactivity, Sharing, Native Excel Exports, App Integration & more > Get technology previously reserved for billion-dollar corporations, FREE > http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk > <http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk> > _______________________________________________ > cx-freeze-users mailing list > cx-freeze-users@lists.sourceforge.net > <mailto:cx-freeze-users@lists.sourceforge.net> > https://lists.sourceforge.net/lists/listinfo/cx-freeze-users > <https://lists.sourceforge.net/lists/listinfo/cx-freeze-users> > > > ------------------------------------------------------------------------------ > Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server > from Actuate! Instantly Supercharge Your Business Reports and Dashboards > with Interactivity, Sharing, Native Excel Exports, App Integration & more > Get technology previously reserved for billion-dollar corporations, FREE > http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk_______________________________________________ > cx-freeze-users mailing list > cx-freeze-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/cx-freeze-users
signature.asc
Description: Message signed with OpenPGP using GPGMail
------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________ cx-freeze-users mailing list cx-freeze-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cx-freeze-users