Reputation: 375
I am trying to create Python service .exe from my code. I've stuck on running it.
I have 2 important files: service code:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
from mailbox.fetcher import main_fetching
from disc.my_logger import set_up_logging
logging = set_up_logging("Fetcher")
class FetcherSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "MailMan-FetchingService"
_svc_display_name_ = "MailMan FetchingService"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop_event = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
logging.info('Stopping fetching ...')
self.stop_requested = True
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
self.main()
def main(self):
logging.info(' ** Starting fetching mails service ** ')
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
while not self.stop_requested:
main_fetching()
The py2exe setup code:
setup(console=[{"script": "fetching_service.py",
"icon_resources": [(1, "../mailman.ico")],
"dest_base": "fetching_service"}],
data_files=[('', ['../cacert.pem', '../trusted-certs.crt'])],
options={"py2exe": {
"includes": ["win32serviceutil", "win32service", "win32event"],
'bundle_files': 0, "optimize": 2,
'dist_dir': 'fetcher_service'}})
The service installs properly:
$ fetcher_service/fetching_service.exe --startup=delayed install
Installing service MailMan-FetchingService
Changing service configuration
Service updated
But on starting:
$ fetcher_service/fetching_service.exe start
Starting service MailMan-FetchingService
Error starting service: Usługa nie odpowiada na sygnał uruchomienia lub sygnał sterujący w oczekiwanym czasie.
(Translating to english: the service did not respond to the start or control request in a timely fashion) I've tries setting specific user, but it did not help... Moreover: error occures INSTANTLY after running, there is no delay
Forgot to add: service works perfectly in debug mode.
Upvotes: 0
Views: 4494
Reputation: 351
This issue can be caused by a broken pywin32 install. Using Sys Internals excellent procmon I found that pythonservice.exe was failing to load pywintypes34.dll. Running c:\python34\scripts\pywin32_postinstall.py fixed the problem. NB if you've installed pywin32 as pypiwin32 because you used pip, then you've need to fix the C:\Python34\Lib\site-packages\pypiwin32_system32 dir to be C:\Python34\Lib\site-packages\pywin32_system32 for the script to work.
Upvotes: 3
Reputation: 375
I have solved the issue. I've used phihag's answer and changes setup.py myself:
setup(service=[{'modules':'fetching_service','cmdline_style':'pywin32','description':'your service description',
# console=[{"script": "fetching_service.py",
"icon_resources": [(1, "../mailman.ico")],
"dest_base": "fetching_service"}],
data_files=[('', ['../cacert.pem', '../trusted-certs.crt'])],
options={"py2exe": {
"includes": ["win32serviceutil", "win32service", "win32event"],
'bundle_files': 0, "optimize": 2,
'dist_dir': 'fetcher_service'}})
Upvotes: 0
Reputation: 288090
You must signal Windows that your service is actually running. Inside SvcDoRun
, call
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
and once your service is actually started (for example once you reach main, or even directly afterwards)
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
to mark your service as sucessfully started.
Upvotes: 1