I know this question was asked so many times. I read all those questions but i didn't find out my problem's solution. My issue is that i have created below window service with help of this link. How do you run a Python script as a service in Windows?
and I am running this service from command prompt.
Here is my python script that i need to run as a service.
import traceback
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import getpass
import json
import pathlib
import urllib.request
import sys
from time import time , sleep
import uuid
from urllib.request import urlopen , Request
from urllib.parse import urlencode , quote_plus
import subprocess
import threading
import requests
from requests.sessions import session
import os
import cgitb
import logging
class PythonService(win32serviceutil.ServiceFramework):
_svc_name_ = "PCSIGN"
_svc_display_name_ = "PC SIGN"
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 ):
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
def main( ):
while True:
file = open ( 'geek.txt' , 'a+' )
file.write("hello world")
file.close()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(PythonService)
PythonService.main()
As you can see in the main function there is an infinite loop in which I am opening a file and writing hello world in it.
I install & start my service from command prompt.
C:\wamp64\www\project\python\New folder>start /min python testing.py install
C:\wamp64\www\project\python\New folder>start /min python testing.py start
after that service installed and start working properly and another window appear.
It also makes an entry successfully in Services.
But the issue here is when i close the above window of python console it stop writing hello world in the file don't know why kindly how can i make it persistent so that whenever system restarted my script start working automatically and start writing hello world in the file
Just a few days back I have successfully sorted out my issue I just made some changes to my code and it started working properly. I am only posting these answers for someone like me who got this issue in the future he can easily sort it out.
This is the new code:
def WriteToFile():
while True:
file = open ( "C:\\file.txt" , "w" )
now = datetime.now()
now = now.strftime("%B %d, %y %H:%M:%S")
file.write(now)
class Pythonservice(win32serviceutil.ServiceFramework):
_svc_name_ = 'PC-Service'
_svc_display_name_ = 'PC-Service'
_svc_description_ = 'Freindly Service'
#classmethod
def parse_command_line(cls):
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
self.stop()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def start(self):
self.isrunning = True
def stop(self):
self.isrunning = False
def main(self):
WriteToFile()
if __name__ == '__main__':
Pythonservice.parse_command_line()
After these changes, I opened up a command prompt as administrator and type this command to install my service.
C:\wamp64\www\project\python\New folder>python testing.py install
I got the success message. After successful installation, I started my service using this command
C:\wamp64\www\project\python\New folder>python testing.py start
and service started successfully I confirmed from service manager as well whether my service is running or not and it was running after restarting my pc service was still in running state.
Related
I have created a test service file in pyhton:
import datetime
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
def writetofile():
DIR = "D:\prog\log.txt"
while True:
with open(DIR, 'a+') as file:
file.write(str(datetime.now()))
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TESTEST"
_svc_display_name_ = "TESTEST"
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):
writetofile()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
I've also installed it but when I want to start in win services it stops every time with 1053 error.
I have tried to overwrite the register file (ServicesPipeTimeout) not worked. I set it up 180000 and nothing. My program ran for a while then stopped again.
I've installed everthing in cmd as admin (pip install pywin32), not worked.
And I've installed the service too in cmd (python main.py install) and I see it, but thats all. I cant start it, cant delete it cant do anything with it.
If I try to do this it doesn't generate the warning:
Test.py install
Test.py start
Otherwise if I use pyinstaller:
pyinstaller -F --hidden-import=win32timezone Test.py
And then I try to do:
Test.exe install
Test.exe start
I see this warning in the event log:
A service process other than the one started by Service Control Manager connected when the TestService service started. Service Control Manager started process 5328 and connected process 1512.
Note that if the service is configured to start inside a debugger, this behavior is expected.
Script:
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
class TestService(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "My service description"
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:
with open('C:\\TestService.log', 'a') as f:
f.write('test service running...\n')
rc = win32event.WaitForSingleObject(self.hWaitStop, 5000)
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(TestService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(TestService)
How can I start the service without this warning appearing?
This is only a warning of windows complaining that the service fired two process.
This is the normal behaviour of pyinstaller executables. You should ignore this kind of warning.
See the docs
My Flask service stops because I logged out in Windows. When I reload my username and password, it works again. How can I make it always on, even when I reboot or log out?
import time
import random
import os
from pathlib import Path
from SMWinservice import SMWinservice
import sys
import win32serviceutil
import win32service
import win32event
import servicemanager
class FlaskService(SMWinservice):
_svc_name_ = "FlaskServiceSmartFactory01"
_svc_display_name_ = "Flask Service Smart Factory01"
_svc_description_ = "Python service framework Smart Factory01"
def start(self):
self.isrunning = True
def stop(self):
self.isrunning = False
def main(self):
os.chdir(os.environ['SMARTFACTORYPATH'])
os.system('C02_RestAPI.py')
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(FlaskService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(FlaskService)
Windows services can run in background when Windows is running but you can't run it if Windows is off.
You can set this service to be load at Windows start if you want.
Using Python 3.7, Windows 10 Pro, Pywin32
I have a test script that starts a service and pushes some basic lines into a log file as the different commands are issued. Code is as follows:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import logging
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "New Test Service"
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Class opened')
def __init__(self, args):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Init')
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Stop')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Run')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
print("running")
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Main')
if __name__ == '__main__':
logging.basicConfig(filename='search_server.log', level=logging.INFO)
logging.info('Calling Handle Command Line')
win32serviceutil.HandleCommandLine(AppServerSvc)
I have gone through the basic trouble shooting with this, and the service is installing, starting, restarting and being removed without any errors. However I am expecting the log file to receive basic output to show the functions are being hit, and it isn't.
The calls I am making at the admin command prompt:
C:\PythonScripts\SearchServer>python servicetest.py install
Installing service TestService
Service installed
C:\PythonScripts\SearchServer>python servicetest.py start
Starting service TestService
C:\PythonScripts\SearchServer>python servicetest.py restart
Restarting service TestService
C:\PythonScripts\SearchServer>python servicetest.py remove
Removing service TestService
Service removed
C:\PythonScripts\SearchServer>
Contents of log file:
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
INFO:root:Class opened
INFO:root:Calling Handle Command Line
As you can see the service is being hit every time a command is issued, however I'd expect the internal functions to be called too. Being new to both services and Python I'm wondering if I've missed anything? I'm assuming the function names are predefined and don't need me to set up delegation to access them. Its not something I've seen in any of the questions I've come across.
I am of course assuming that these functions are supposed to be hit and they are being hit and are capable of creating logs?
Any help gratefully received.
There are a few problems with the code:
logging.basicConfig() should be called only once, if called again it won't have any effect.
Class definition will be called first in your code, even before block if __name__ == '__main__': because of natural flow of code. Due to this, whatever you set in logging.basicConfig() in class definition will become final for whole script. It is not an ideal place for this setting, so should be moved elsewhere (at the top, outside the class preferably).
filename parameter passed in the logging.basicConfig should be the absolute file path, because once service starts running, its current path won't be the same as the script, so logging won't be able to find out the log file. (current working directory for the service would become something like C:\Python37\lib\site-packages\win32).
(Optional): Try not to use root logging config at all, it's better to have an instance of logger for your own use.
After all these changes, the script will look like this:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import logging.handlers
log_file_path = "" # mention full path here
mylogger = logging.getLogger("TestLogger")
mylogger.setLevel(logging.INFO)
handler = logging.handlers.RotatingFileHandler(log_file_path)
mylogger.addHandler(handler)
class AppServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "New Test Service"
mylogger.info('Class opened')
def __init__(self, args):
mylogger.info('Init')
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
mylogger.info('Stop')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
mylogger.info('Run')
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
print("running")
mylogger.info('Main')
if __name__ == '__main__':
mylogger.info('Calling Handle Command Line')
win32serviceutil.HandleCommandLine(AppServerSvc)
Output:
Class opened
Init
Run
Main
Class opened
Calling Handle Command Line
I've had unexplainable problems with python logging, I solved them by setting up the logging right at the beginning of the program:
import logging
logging.basicConfig(filename='convert_st.log', level=logging.INFO)
logging.info('Started')
import all_other_packages
import...
...
def main:
# main comes here
...
if __name__ == '__main__':
main()
What I'm trying to do is to write a script which would open an application only in process list. Meaning it would be "hidden". I don't even know if its possible in python.
If its not possible, I would settle for even a function that would allow for a program to be opened with python in a minimized state maybe something like this:
import subprocess
def startProgram():
subprocess.Hide(subprocess.Popen('C:\test.exe')) # I know this is wrong but you get the idea...
startProgram()
Someone suggested to use win32com.client but the thing is that the program that i want to launch doesn't have a COM server registered under the name.
Any ideas?
It's easy :)
Python Popen Accept STARTUPINFO Structure...
About STARTUPINFO Structure: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
Run Hidden:
import subprocess
def startProgram():
SW_HIDE = 0
info = subprocess.STARTUPINFO()
info.dwFlags = subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = SW_HIDE
subprocess.Popen(r'C:\test.exe', startupinfo=info)
startProgram()
Run Minimized:
import subprocess
def startProgram():
SW_MINIMIZE = 6
info = subprocess.STARTUPINFO()
info.dwFlags = subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = SW_MINIMIZE
subprocess.Popen(r'C:\test.exe', startupinfo=info)
startProgram()
You should use win32api and hide your window e.g. using win32gui.EnumWindows you can enumerate all top windows and hide your window
Here is a small example, you may do something like this:
import subprocess
import win32gui
import time
proc = subprocess.Popen(["notepad.exe"])
# lets wait a bit to app to start
time.sleep(3)
def enumWindowFunc(hwnd, windowList):
""" win32gui.EnumWindows() callback """
text = win32gui.GetWindowText(hwnd)
className = win32gui.GetClassName(hwnd)
#print hwnd, text, className
if text.find("Notepad") >= 0:
windowList.append((hwnd, text, className))
myWindows = []
# enumerate thru all top windows and get windows which are ours
win32gui.EnumWindows(enumWindowFunc, myWindows)
# now hide my windows, we can actually check process info from GetWindowThreadProcessId
# http://msdn.microsoft.com/en-us/library/ms633522(VS.85).aspx
for hwnd, text, className in myWindows:
win32gui.ShowWindow(hwnd, False)
# as our notepad is now hidden
# you will have to kill notepad in taskmanager to get past next line
proc.wait()
print "finished."
What is the purpose?
if you want a hidden(no window) process working in background, best way would be to write a windows service and start/stop it using usual window service mechanism. Windows service can be easily written in python e.g. here is part of my own service (it will not run without some modifications)
import os
import time
import traceback
import pythoncom
import win32serviceutil
import win32service
import win32event
import servicemanager
import jagteraho
class JagteRahoService (win32serviceutil.ServiceFramework):
_svc_name_ = "JagteRaho"
_svc_display_name_ = "JagteRaho (KeepAlive) Service"
_svc_description_ = "Used for keeping important services e.g. broadband connection up"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.stop = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.log('stopping')
self.stop = True
def log(self, msg):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,msg))
def SvcDoRun(self):
self.log('folder %s'%os.getcwd())
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.start()
def shouldStop(self):
return self.stop
def start(self):
try:
configFile = os.path.join(jagteraho.getAppFolder(), "jagteraho.cfg")
jagteraho.start_config(configFile, self.shouldStop)
except Exception,e:
self.log(" stopped due to eror %s [%s]" % (e, traceback.format_exc()))
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
and you can install it by
python svc_jagteraho.py--startup auto install
and run it by
python python svc_jagteraho.py start
I will be also be seen in services list e.g. services.msc will show it and you can start/stop it else you can use commandline
sc stop jagteraho
Run Hidden:
from subprocess_maximize import Popen
Popen("notepad.exe",show='hidden', priority=0)
Before the code above, use the following command:
pip install subprocess-maximize
If what is appearing is a terminal, redirect the process's stdout.