I was able to create a python service on windows 10 using this example: Is it possible to write a windows (10) service with python (standard python.org python) without compiling
Then I created a separate python file using mss to take a single screenshot of monitor 1. Everything worked fine when I run them separately. However, when i replace the text file code in the def main(self) with the screenshot code, the resulting image file is just black.
Feel like the monitor number isn't being accessed in the service, but not sure why or even if that is the issue.
Edit: The image isn't blank it's black. Updated above from blank to black.
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import mss
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
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):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
def main(self):
# Your business logic or call to any class should be here
with mss.mss() as sct:
filename = sct.shot(output="C:\\Output\\mon-{mon}-.png")
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
Related
I wrote a simple python http server to serve the files(folders) of the present working directory.
import socketserver
http=''
def httpServer(hostIpAddress):
global http
socketserver.TCPServer.allow_reuse_address=True
try:
with socketserver.TCPServer((hostIpAddress,22818),SimpleHTTPRequestHandler) as http:
print(1123)
http.serve_forever()
except Exception as e:
print(str(e))
if __name__ == '__main__':
httpServer('192.168.1.2')
this code works as expected .It serves the contents.
However when i Freeze it (convert ist to executable) using cx-freeze . It does not serve the files .IN chrome it outs ERR_EMPTY_RESPONSE. I tried other browsers but to no avail.
My setup.py for the freeze is
executables = [
Executable("test_http.py", base=base,target_name="test_http",shortcutName="test_http",shortcutDir="DesktopFolder")
]
setup(
name="test_http",
options={"build_exe":build_exe_option,"bdist_msi":bdist_msi_options},
executables=executables
)
The .exe works without any error and you can even see the program running in task manager.
i used:
cx-freeze(i tried version 6.6,6.7,6.8)
python 3.7.7 32 bits
os : windpows 8.1
Thanks in advance.
Instead of using a function httpserver , I used class and it build the exe without any problem and now the http server runs even in its executable form.
Credit to: https://stackoverflow.com/users/642070/tdelaney for providing this solution at :
https://pastebin.com/KsTmVWRZ
import http.server
import threading
import functools
import time
# Example simple http server as thread
class SilentHandler(http.server.SimpleHTTPRequestHandler):
def log_message(self, format, *args, **kwargs):
# do any logging you like there
pass
class MyHttpServerThread(threading.Thread):
def __init__(self, address=("0.0.0.0",8000), target_dir="."):
super().__init__()
self.address = address
self.target_dir = "."
self.server = http.server.HTTPServer(address, functools.partial(SilentHandler, directory=self.target_dir))
self.start()
def run(self):
self.server.serve_forever(poll_interval=1)
def stop(self):
self.server.shutdown() # don't call from this thread
# test
if __name__ == "__main__":
http_server = MyHttpServerThread()
time.sleep(10)
http_server.stop()
print("done")
I want to run some Python code as a service on Windows. I use Python 3.6 by the way.
I have put together (from various sources) this generalized windows daemon class. When I run it, it works well. However, when I subclass this to use in a service that contains some actual useful code, the service is not started but returns immediately with error The service did not respond to the start or control request in a timely fashion.
So - see example below - windows_daemon.py works, but new_service.py does not.
Can anyone see why my python service does not start on windows when I subclass it?
windows_daemon.py
import time
import sys
import logging
import logging.handlers
import traceback
import win32serviceutil
import win32service
import win32event
import servicemanager
import os
def handle(instance):
win32serviceutil.HandleCommandLine(instance)
class windows_daemon(win32serviceutil.ServiceFramework):
# you can NET START/STOP the service by the following name
_svc_name_ = "Daemon"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "Windows daemon"
# this text shows up as the description in the SCM
_svc_description_ = "This service controls some stuff"
# list dependencies
_svc_deps_ = ["EventLog"]
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self,args)
# create an event to listen for stop requests on
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
self.Alive = True
self.host = os.environ['COMPUTERNAME'].lower()
self.pid = os.getpid()
self.name = self._svc_display_name_
self.rootlogger = logging.getLogger()
#self.logger = logging.getLogger("{}".format(self.name))
self.rootlogger.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.handlers.RotatingFileHandler("{0}\log\{1}.log".format(os.path.dirname(os.path.realpath(__file__)), self.name), maxBytes = 1000000, backupCount = 5)
handler.setFormatter(formatter)
self.rootlogger.addHandler(handler)
self.logger = logging.getLogger("service")
# called when we're being shut down
def SvcStop(self):
self.logger.info("stopping service")
# tell the SCM we're shutting down
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
# fire the stop event
win32event.SetEvent(self.hWaitStop)
self.Alive = False
# core logic of the service
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.logger.debug("starting service")
self.timeout = 100
try:
self.main()
self.logger.debug("no exception in main")
exitcode = 0
except Exception as e:
#could also debug to Windows event log
#servicemanager.LogErrorMsg(traceback.format_exc())
#servicemanager.LogErrorMsg("{}".format(e))
try:
self.logger.error(e)
self.logger.error(traceback.format_exc())
except Exception as e:
pass
# servicemanager.LogErrorMsg("{}".format(e))
#return some value other than 0 to os so that service knows to restart
self.logger.error("some exception in main")
exitcode = -1
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
self.logger.info("stopped with exit code {}".format(exitcode))
os._exit(exitcode)
def check_for_signals(self, timeout = 100):
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
def main(self):
# override in subclass
print("this is function main() that should be subclassed")
#time.sleep(1)
pass
if __name__ == '__main__':
handle(windows_daemon)
print("you should subclass windows_daemon from this module")
new_service.py
from windows_daemon import windows_daemon, handle
import time
import sys
import win32serviceutil
class New_service(windows_daemon):
# you can NET START/STOP the service by the following name
_svc_name_ = "NEW"
# this text shows up as the service name in the Service
# Control Manager (SCM)
_svc_display_name_ = "New service"
# this text shows up as the description in the SCM
_svc_description_ = "This service exists as a template for new services"
# override dependencies?
# _svc_deps_ = ["EventLog"]
def __init__(self, args):
print(super())
super().__init__(args)
def main(self):
time.sleep(10)
if __name__ == '__main__':
sys.frozen = 'windows_exe'
handle(New_service)
Apparently, this line caused the problem. I found that by learning about the python debugging module (pdb) and using it to investigate.
sys.frozen = 'windows_exe'
When I removed this line, the new_service.py also ran. Hope this helps someone in the future.
I've implemented a windows service, this service has no problem before compiling with pyinstaller but after that on service start command it gives 1053 error.
Windows service code:
import sys
import win32service
import win32event
import socket
import win32api
import win32serviceutil
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "test"
_svc_display_name_ = "test"
_stoped = False
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self._stoped = True
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.main()
def main(self):
while True:
if self._stoped:
break
pass
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
Finally i solved this problem, there was a broken link to one of references in windows service. This is the right config for py2exe which solved my problem:
opts = {'py2exe': {
'dll_excludes': ['libzmq.pyd', 'OLEAUT32.dll', 'USER32.dll', 'SHELL32.dll', 'ole32.dll',
'MSVCP90.dll', 'ADVAPI32.dll', 'NETAPI32.dll', 'WS2_32.dll', 'GDI32.dll',
'VERSION.dll', 'KERNEL32.dll', 'WINSPOOL.DRV', 'mfc90.dll', 'ntdll.dll'],
'includes': ['UserList', 'UserString', 'commands', 'zmq.backend.cython'],
'dist_dir': "dist"
}}
setup(service=[service], options=opts, zipfile=None,data_files=[(os.path.join(os.getcwd(), 'dist'), (zmq.libzmq.__file__,))])
To use my win32serviceutil.ServiceFramework class in an exe pyInstaller produced, I needed to add a few .pyd files to the directory containing the exe e.g. win32service.pyd and win32event.pyd. Assuming you've used the standard install paths for your libraries, these files are found here:
C:\Python27\Lib\site-packages\win32
I coded out a windows service in python to write some text to a file continuously and installed it and ran it and it works fine. Now if I try to convert my python windows service script into an executable (.exe) using py2exe. The .exe installs fine as a service but when I try to start it I get the error "The server did not respond to the start ......in timely fashion". Is this got something to do with py2exe destroying information in my python script. How do I go around this? (I am trying to convert it to a .exe because I want to distribute it).
My python script is as follows:
import win32service
import win32serviceutil
import win32event
class clear_queue(win32serviceutil.ServiceFramework):
_svc_name_ = "avant"
_svc_display_name_ = "avant"
_svc_description_ = "Elegant file writer"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
import servicemanager;
fil = open("C:/Users/u/Desktop/c99/user.txt",'r+');
rc = win32event.WaitForSingleObject(self.hWaitStop, 64)
while rc != win32event.WAIT_OBJECT_0:
fil.write("george\n");
rc = win32event.WaitForSingleObject(self.hWaitStop, 64)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(clear_queue)
Looking at the example at http://tools.cherrypy.org/wiki/WindowsService, it looks like you need to add self.ReportServiceStatus(win32service.SERVICE_STOPPED) as the final line of the SvcStop method.
below is my code that I am trying to turn into a windows service. You'll see test.py as the call it makes and all this is a short script that writes into a log file (as a test).
The code is there to make it a windows service and it does that fine, but when I run it nothing writes into the log file. Help greatly appreciated. Below is the code:
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os, sys, string, time
class aservice(win32serviceutil.ServiceFramework):
_svc_name_ = "MyServiceShortName"
_svc_display_name_ = "A python test"
_svc_description_ = "Writing to a log"
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 = 1000 #1 seconds
# 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
servicemanager.LogInfoMsg("SomeShortNameVersion - STOPPED!") #For Event Log
break
else:
#what to run
try:
file_path = "test.py"
execfile(file_path)
except:
pass
#end of what to run
def ctrlHandler(ctrlType):
return True
if __name__ == '__main__':
win32api.SetConsoleCtrlHandler(ctrlHandler, True)
win32serviceutil.HandleCommandLine(aservice)
Edit: Thought for the sake of it I'd include my test.py file's code, it has unnecessary imports but will get the job done if you run it alone.
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os
logfile = open("log.txt", "a") #open file to log restart timestamp
logfile.write("\nthat's good!!!!")
logfile.close()
Okay so I figured it out and would like to come back and post in case anyone else is dealing with this, all though this was a tad unique.
You have to specify your file path if you are within a windows service, duh... but it wasn't done and I pulled my hair out for no reason.
file_path = "test.py"
should have been
file_path = r"c:\users\...\test.py"
Be careful when using '\' for windows file paths. They must be escaped like '\\' or the string must be declared as raw string ('r'). Using the unix like slash '/' separators works also but may look odd for windows users.