यह उत्तर StackOverflow पर कई स्रोतों से साहित्यिक चोरी है - उनमें से अधिकांश ऊपर, लेकिन मैं दूसरों को भूल गया हूं - क्षमा करें। यह सरल है और स्क्रिप्ट "जैसा है" चलती है। रिलीज़ के लिए आप स्क्रिप्ट का परीक्षण करते हैं, फिर इसे सर्वर पर कॉपी करें और संबंधित सेवा को रोकें / प्रारंभ करें। और यह सभी स्क्रिप्टिंग भाषाओं (पायथन, पर्ल, नोड.जेएस), प्लस बैच स्क्रिप्ट जैसे कि GitBash, PowerShell, यहां तक कि पुरानी DOS बैट स्क्रिप्ट के लिए काम करना चाहिए। pyGlue वह गोंद है जो विंडोज सर्विसेज और आपकी स्क्रिप्ट के बीच बैठता है।
'''
A script to create a Windows Service, which, when started, will run an executable with the specified parameters.
Optionally, you can also specify a startup directory
To use this script you MUST define (in class Service)
1. A name for your service (short - preferably no spaces)
2. A display name for your service (the name visibile in Windows Services)
3. A description for your service (long details visible when you inspect the service in Windows Services)
4. The full path of the executable (usually C:/Python38/python.exe or C:WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe
5. The script which Python or PowerShell will run(or specify None if your executable is standalone - in which case you don't need pyGlue)
6. The startup directory (or specify None)
7. Any parameters for your script (or for your executable if you have no script)
NOTE: This does not make a portable script.
The associated '_svc_name.exe' in the dist folder will only work if the executable,
(and any optional startup directory) actually exist in those locations on the target system
Usage: 'pyGlue.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'
Options for 'install' and 'update' commands only:
--username domain\\username : The Username the service is to run under
--password password : The password for the username
--startup [manual|auto|disabled|delayed] : How the service starts, default = manual
--interactive : Allow the service to interact with the desktop.
--perfmonini file: .ini file to use for registering performance monitor data
--perfmondll file: .dll file to use when querying the service for performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
--wait seconds: Wait for the service to actually start or stop.
If you specify --wait with the 'stop' option, the service and all dependent services will be stopped,
each waiting the specified period.
'''
import servicemanager
import socket
import sys
import win32event
import win32service
import win32serviceutil
import win32evtlogutil
import os
from logging import Formatter, Handler
import logging
import subprocess
class Service (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
_svc_description_ = "Test Running Python Scripts as a Service"
service_exe = 'c:/Python27/python.exe'
service_script = None
service_params = []
service_startDir = None
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self.configure_logging()
socket.setdefaulttimeout(60)
def configure_logging(self):
self.formatter = Formatter('%(message)s')
self.handler = logHandler()
self.handler.setFormatter(self.formatter)
self.logger = logging.getLogger()
self.logger.addHandler(self.handler)
self.logger.setLevel(logging.INFO)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.main()
def main(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
logging.info('%s - about to call Popen() to run %s %s %s', self._svc_name_, self.service_exe, self.service_script, self.service_params)
self.process = subprocess.Popen([self.service_exe, self.service_script] + self.service_params, shell=False, cwd=self.service_startDir)
logging.info('%s - started process %d', self._svc_name_, self.process.pid)
rc = None
while rc != win32event.WAIT_OBJECT_0:
rc = win32event.WaitForSingleObject(self.hWaitStop, (1 * 60 * 1000))
logging.info('%s - is terminating process %d', self._svc_name_, self.process.pid)
self.process.terminate()
logging.info('%s - is exiting', self._svc_name_)
class logHandler(Handler):
'''
Emit a log record to the WINDOWS Event log
'''
def emit(self, record):
servicemanager.LogInfoMsg(record.getMessage())
if __name__ == '__main__':
'''
Create a Windows Service, which, when started, will run an executable with the specified parameters.
'''
if not os.path.isfile(Service.service_exe):
print('Executable file({!s}) does not exist'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
if not os.access(Service.service_exe, os.X_OK):
print('Executable file({!s}) is not executable'.format(Service.service_exe), file=sys.stderr)
sys.exit(0)
if (Service.service_startDir is not None) and (not os.path.isdir(Service.service_startDir)):
print('Start up directory({!s}) does not exist'.format(Service.service_startDir), file=sys.stderr)
sys.exit(0)
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)
अब संपादन का एक सा है और आप 'pyGlue' नामक अपनी सभी सेवाओं को नहीं चाहते हैं। तो बिट्स में प्लग करने के लिए एक स्क्रिप्ट (build.sh) है और एक अनुकूलित 'pyGlue' और एक '.exe' बनाएं। यह यह '.exe' है जो विंडोज सर्विस के रूप में स्थापित हो जाता है। एक बार स्थापित होने के बाद आप इसे स्वचालित रूप से चलाने के लिए सेट कर सकते हैं।
if [ $
echo "Usage: build.sh Name Display Description Executable Script StartupDir [Params]..."
exit 0
fi
name=$1
display=$2
desc=$3
exe=$4
script=$5
startDir=$6
shift; shift; shift; shift; shift; shift
params=
while [ $
if [ "${params}" != "" ]; then
params="${params}, "
fi
params="${params}'$1'"
shift
done
cat pyGlue.py | sed -e "s/pyGlue/${name}/g" | \
sed -e "/_svc_name_ =/s?=.*?= '${name}'?" | \
sed -e "/_svc_display_name_ =/s?=.*?= '${display}'?" | \
sed -e "/_svc_description_ =/s?=.*?= '${desc}'?" | \
sed -e "/service_exe =/s?=.*?= '$exe'?" | \
sed -e "/service_script =/s?=.*?= '$script'?" | \
sed -e "/service_params =/s?=.*?= [${params}]?" | \
sed -e "/service_startDir =/s?=.*?= '${startDir}'?" > ${name}.py
cxfreeze ${name}.py --include-modules=win32timezone
स्थापना - निर्दिष्ट फ़ोल्डर में '.exe' सर्वर और स्क्रिप्ट की प्रतिलिपि बनाएँ। 'इंस्टाल' विकल्प के साथ प्रशासक के रूप में '.exe' चलाएं। व्यवस्थापक के रूप में, Windows सेवाएँ खोलें और आप सेवा शुरू करें। अपग्रेड के लिए, बस स्क्रिप्ट के नए संस्करण को कॉपी करें और सेवा को रोकें / शुरू करें।
अब हर सर्वर अलग है - पायथन की अलग-अलग स्थापना, अलग-अलग फ़ोल्डर संरचनाएँ। मैं pyGlue.py और build.sh की एक प्रति के साथ, हर सर्वर के लिए एक फ़ोल्डर बनाए रखता हूं। और मैं उस सर्वर पर सभी सेवा के पुनर्निर्माण के लिए एक 'serverBuild.sh' स्क्रिप्ट बनाता हूं।
sh build.sh AutoCode 'AutoCode Medical Documents' 'Autocode Medical Documents to SNOMED_CT and AIHW codes' C:/Python38/python.exe autocode.py C:/Users/russell/Documents/autocoding -S -T