Run Python as windows a service - call another python scrip with modules - python

Im trying to run python as windows service.
The following this post is working okay: https://gist.github.com/guillaumevincent/d8d94a0a44a7ec13def7f96bfb713d3f
But when I try to import some of my other python and call from this service it wont work.
code of service :
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
import datetime
# impoort own module
from modules import copy_log
class TestService(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService7"
_svc_display_name_ = "Test Service7"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
rc = None
while rc != win32event.WAIT_OBJECT_0:
now = datetime.datetime.now()
with open('C:\\test\\TestService.log', 'a') as f:
self.count = self.count + 1
f.write(str(self.count) + ' :: '+str(now) + '\n')
f.write('________________\n')
f.write('test service running...\n')
#call own module
"Here is simple function im my seprare python project and is not working"
copy_log.CopyTest()
rc = win32event.WaitForSingleObject(self.hWaitStop, 1000*10)
def main(self):
pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(TestService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(TestService)
example of file/module that is called by python service:
import datetime
from shutil import copyfile
class CopyTest(object):
def __init__(self):
print(self.__str__())
pass
def copy_it(self):
copyfile("C://test_read/aaa.txt",
"C:///test_write/aaa.txt")
and is not working that. I don't know why?

Related

Python Win32 service doesnt start except in debug mode

I have a Django app that I'm trying to run via Cherrypy on Windows Server. I have below code in the service creation script.
import os
import sys
service_directory = os.path.dirname(__file__)
source_directory = os.path.abspath(service_directory)
os.chdir(source_directory)
venv_base = os.path.abspath(os.path.join(source_directory, ".venv"))
print(venv_base)
sys.path.append(".")
old_os_path = os.environ['PATH']
os.environ['PATH'] = os.path.join(venv_base, "Scripts")+ os.pathsep + old_os_path
site_packages = os.path.join(venv_base, "Lib", "site-packages")
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = venv_base
new_sys_path = list()
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
import pathlib
import subprocess
import traceback
import servicemanager
import win32event
import win32service
import win32serviceutil
from win32api import SetConsoleCtrlHandler
class AppServerSvc(win32serviceutil.ServiceFramework):
"""
Service Create class
"""
_svc_name_ = "MyService" # service name
_svc_display_name_ = "MyService" # display name
def __init__(self, args):
"""
Constructor
"""
win32serviceutil.ServiceFramework.__init__(self, args)
SetConsoleCtrlHandler(lambda x: True, True)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
"""
Function to stop the windows service
"""
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.proc.terminate()
def SvcDoRun(self):
"""
Function to create and start the windows service
"""
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
try:
self.main()
except Exception as exp_msg:
servicemanager.LogErrorMsg(traceback.format_exc())
os._exit(-1)
def main(self):
"""
Script to run as the windows service
"""
#env_file.load(f'{os.path.join(pathlib.Path(__file__).parent.absolute(), "config.env")}')
#settings.set_env_variables()
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.proc = subprocess.Popen(f"python"
f" {os.path.join(pathlib.Path(__file__).parent.absolute(), 'cherryd.py')} 1"
, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
stdin=subprocess.DEVNULL)
stdout, stderr = self.proc.communicate()
print(stdout)
if (self.proc.poll() == 0):
servicemanager.LogMsg(f"Successfully started the process with PID: {self.proc.pid}")
else:
servicemanager.LogErrorMsg(f"Failed to start the services")
if __name__ == '__main__':
# Start of the process
win32serviceutil.HandleCommandLine(AppServerSvc)
I'm able to install this service using python service.py install, no issues here.
When I start the service python service.py start I get error Error starting service: The service did not respond to the start or control request in a timely fashion.
When I do python service.py debug, everything works normal and I'm able to access the app using FQDN. Why does the service not work when started normally and work only during debug mode.
Have read multiple posts on similar errors but nothing helped. I'm using Python 3.8 and have added the venv Scripts directory to PATH as well. Can someone please help.
Update
Started the service with my user account and it worked, still don't understand how it worked in debug mode.

Why doesnt exec() or os.system work within pywin32 windows service?

### Run Python scripts as a service example (ryrobes.com)
### Usage : python aservice.py install (or / then start, stop, remove)
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os, sys, string, time
class aservice(win32serviceutil.ServiceFramework):
_svc_name_ = " Service"
_svc_display_name_ = " Service"
_svc_description_ = "Extract "
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
#self.timeout = 640000 #640 seconds / 10 minutes (value is in milliseconds)
self.timeout = 10000 #120 seconds / 2 minutes
# This is how long the service will wait to run / refresh itself (see script below)
while 1:
# Wait for service stop signal, if I timeout, loop again
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
# Stop signal encountered
os.system("old_data.py")
servicemanager.LogInfoMsg("Service - STOPPED!") #For Event Log
break
else:
#Ok, here's the real money shot right here.
#[actual service code between rests]
try:
os.system("old_data.py")
servicemanager.LogInfoMsg("OLD DATA UPDATED!")
#file_path = "C:\whereever\my_REAL_py_work_to_be_done.py"
exec(open("file.py").read()) #Execute the script
servicemanager.LogInfoMsg("Service - STARTED!")
#inc_file_path2 = "C:\whereever\MORE_REAL_py_work_to_be_done.py"
#exec(open(r"").read()) #Execute the script
except:
pass
#[actual service code between rests]

Windows service with Flask only run in DEBUG mode. Normal mode seem crash

I want to install python script (use Flask) as Windows service.
I use simple code as below (in myservice.py) :
import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import servicemanager
import socket
import time
import logging
from multiprocessing import Process
import traceback
import logging
from datetime import datetime,tzinfo,timedelta
from flask import Flask
import os
import sys
sys.path.append(os.path.dirname(__name__))
app = Flask(__name__)
class Zone(tzinfo):
def __init__(self,offset,isdst,name):
self.offset = offset
self.isdst = isdst
self.name = name
def utcoffset(self, dt):
return timedelta(hours=self.offset) + self.dst(dt)
def dst(self, dt):
return timedelta(hours=1) if self.isdst else timedelta(0)
def tzname(self,dt):
return self.name
#app.route('/')
def hello_world():
logging.info('[GET] hello_world ...')
KST = Zone(+9,False,'KST')
now_time = datetime.now(KST).strftime('%Y-%m-%d %H:%M:%S %Z')
return 'Hello, World! ' + now_time
logging.basicConfig(
filename = 'c:\\Temp\\hello-service.log',
level = logging.DEBUG,
format = '[helloflask] %(levelname)-7.7s %(message)s'
)
class HelloFlaskSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "AIHello"
_svc_display_name_ = "AI Hello"
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
#socket.setdefaulttimeout(5)
self.stop_requested = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
#self.process.terminate()
win32event.SetEvent(self.hWaitStop)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
logging.info('Stopped service ...')
self.stop_requested = True
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'')
)
logging.info('Before main')
app.run()
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(HelloFlaskSvc)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(HelloFlaskSvc)
I can install this script by command : python.exe myservice.py -install, it show up in Services list, but when i try to start it say "The AI Hello service on Local Computer started and then stopped. Some service stop automatically if they are not in use by other services or program".
I checked Event Viewer log, it show " The instance's SvcRun() method failed
.Error getting traceback - traceback.print_exception() failed %2: %3"
I am using Python 3.6.4 , Flask 1.0.2, pywin32-224, on Windows 10 64bit.
This script can work in DEBUG mode by command: python myservice.py debug
Hope somebody can help me out, please
Updated: I switched to Python 2.7. It show the same error. But in Event Viewer log:
The instance's SvcRun() method failed
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\win32\lib\win32serviceutil.py", line 839, in SvcRun
self.SvcDoRun()
File "D:\MusFatAI\FlaskServiceWin32-master\FlaskServiceWin32-master\win32_service.py", line 73, in SvcDoRun
app.run(debug=False)
File "C:\Python27\lib\site-packages\flask\app.py", line 938, in run
cli.show_server_banner(self.env, self.debug, self.name, False)
File "C:\Python27\lib\site-packages\flask\cli.py", line 629, in show_server_banner
click.echo(message)
File "C:\Python27\lib\site-packages\click\utils.py", line 261, in echo
file.flush()
IOError: (9, 'Bad file descriptor')
I had similar problem and I fixed it by putting this line on top of the script:
sys.stdout = sys.stderr = open(os.devnull, 'w')

Python has stopped working(3.7)while installing window service

I am creating window service using python(python3.7.0).
import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import time
import sys
class BRSService(win32serviceutil.ServiceFramework):
_svc_name_ = 'BRS'
_svc_display_name_ = 'BRS'
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
self.isAlive = True
def SvcStop(self):
self.isAlive = False
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.isAlive = True
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ''))
self.main()
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
def main(self):
#i = 0
while self.isAlive:
print ("Service alive")
time.sleep(86400)
#pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(BRSService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(BRSService)
So when I run the command "BRS.py install".
The window message is coming "python has stopped working".
Looks like some problem while calling "win32serviceutil.HandleCommandLine" function.
i meet the same problem, and i use the same as you ,Python 3.7 64bit, meet stop working also.
now i found if use Python 3.6.4 64bit. no error raise. you can try.

Using py2exe to create windows service

I need to run my python app as windows service.
I'm able to do that using commands,python fservice.py install
python fservice.py start
Now, i want to create exe for my app using py2exe.
I've followed code from this question: link
setup.py
from distutils.core import setup
import py2exe
import sys
if len(sys.argv) == 1:
sys.argv.append("py2exe")
sys.argv.append("-q")
class Target:
def __init__(self, **kw):
self.__dict__.update(kw)
# for the versioninfo resources
self.version = "0.0.1"
self.company_name = "flotomate"
self.copyright = "no copyright"
self.name = "flotomate"
myservice = Target(
# used for the versioninfo resource
description = "flotomate",
# what to build. For a service, the module name (not the
# filename) must be specified!
modules = ["fservice"]
)
setup(
service = [myservice]
)
fservice.py
import sys
import servicemanager
import win32serviceutil
import win32service
import win32event
import win32api
from pagent import app
class fservice(win32serviceutil.ServiceFramework):
_svc_name_ = 'flotomate' #here is now the name you would input as an arg for instart
_svc_display_name_ = 'flotomate' #arg for instart
_svc_description_ = 'flotomate'# arg from instart
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
#logs into the system event log
def log(self, msg):
import servicemanager
servicemanager.LogInfoMsg(str(msg))
def sleep(self, minute):
win32api.Sleep((minute*1000), True)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('start')
self.start()
self.log('wait')
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
self.log('done')
except Exception:
self.SvcStop()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def start(self):
app.run(host='0.0.0.0',port=4999)
# to be overridden
def stop(self):
pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(fservice)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(fservice)
I'm creating exe using command,python setup.py py2exe
but, when i try to install the service using fservice.exe --install
I get this error
Traceback (most recent call last):
File "boot_service.py", line 37, in <module>
AttributeError: 'module' object has no attribute 'Initialize
boot_service.py of py2exe
I'm using Python 2.7.6 and py2exe-0.6.9
I encountered the same problem. I don't know whether you found the solution yet
In my case, the reason would be that servicemanager is not included in the compiled package. It seems the installed servicemanager library in python issues conflict.
To solve this problem, I uninstall servicemanager if it is unused or manually copy servicemanager.pyd to folder dist and servicemager.pyc to dist\library.zip. If there is a folder named servicemanager in dist\library.zip, just delete it.
If you already had a better solution, please share it ^^

Categories

Resources