Jorge
Jorge

Reputation: 31

Problems involving py2exe & python services

My goal is to create a single (or mutliple) .exe that can be used to install a Windows system service. Currently this is just a proof of concept so all my service does is write to a file to confirm it's existence.

When I invoke the service from a .py file it installs and runs fine. When I make a .exe out of it using py2exe, it will run fine, however I do get some messages in the Windows Event Log (Application) that certain libraries are not found. Sometimes windows stops the service after startup, sometimes windows ignores the "module not found" errors. All of this takes place on a XP SP3 machine.

When I move the same .exe compiled w/py2exe to a Win 7 SP1 machine, win7 informs me that the .exe cannot run without python27.dll. So I move python27.dll in the cwd of the .exe, and Win 7 then tells me it has failed to load the .dll. When I try to run the .exe on a XP SP2 machine, XP tells me that the file cannot be loaded.

Here is the corresponding code:

PySvc.py (This is the actual service, PySvc.py install is the string used to install it from the prompt :

import win32service  
import win32serviceutil  
import win32event
import servicemanager

class PySvc(win32serviceutil.ServiceFramework):  
    _svc_name_ = "PySvc"  

    _svc_display_name_ = "Python Test"  
    _svc_description_ = "Service Test"  

    def __init__(self, args):  
        win32serviceutil.ServiceFramework.__init__(self,args)  
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)  

    # Meat and potatos. This is the actual code that's run. Currently testing
    # to see behavior inside and outside of loop.
    def SvcDoRun(self):  


        f = open('test.dat', 'w+')  
        rc = None  
        f.write('OUTSIDE L00P\n')  
        # continue iteration if stop event not recieved  
        while rc != win32event.WAIT_OBJECT_0:  
            f.write('BEAUTIFUL TEST DATA NEW INSIDE L00P\n')  
            f.flush()  
            # block for 5 seconds and listen for a stop event  
            rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)  

        f.write('SHUTTING DOWN\n')  
        f.close()  

    # called on shut down      
    def SvcStop(self):  
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)  
        win32event.SetEvent(self.hWaitStop)  

if __name__ == '__main__':  
    win32serviceutil.HandleCommandLine(PySvc) 

The following is the code for "setup.py". Setup.py py2exe is the string used to create the .exe.

from distutils.core import setup
import py2exe





setup(
            name = 'PySvc',
            description = 'Service Test',
            version = '1.00.00',
                service = ['PySvc'],

                console = ['PySvc.py'],
                zipfile=None,
                options = {
                                "py2exe":{
                                           "includes":"win32service,win32serviceutil,win32event,servicemanager",


                                    },
                            },
    )                            

Due to the .exe's apparent success on the local machine but failure on several other machines (that do not have python installed), I am currently inclined to believe that this is a problem with imports or the way that the imports are being compiled. I would be eternally grateful if anyone could provide some insight as to why this .exe doesn't want to behave as it should. Thank you for your time.

Upvotes: 1

Views: 997

Answers (1)

BigHandsome
BigHandsome

Reputation: 5403

I cannot be 100% sure without a little more information, but, I ran into a similar issue. It turned out that in Python 2.6, 2.7, 3.0, 3.1 you need to bundle the c runtime dll yourself with your package.

Because you have python already installed, you likely have it. Your end user will likely not. You can find out more about this issue on on py2exe's website.

Upvotes: 1

Related Questions