Windows服务中的Python子进程(无管道)

时间:2014-08-10 23:40:45

标签: python windows service subprocess popen

我使用CherryPy组装了一个简单的python Web服务器。它作为我已经制作的Web应用程序的打印机,以便Web应用程序可以将POST详细信息打印到localhost。 Web应用程序本身由远程计算机提供。本地python服务器构建一个postscript文件,然后使用Ghostscript子进程打印出来。

当我从命令行启动python脚本时,它工作正常,但对于生产我希望它作为Windows服务运行。因此,我把它变成了一个,但是我的subprocess.Popen没有很好地进行转换。它得到200响应,postscript文件生成正确,但Ghostscript没有做任何事情。

我已经搜索了这个问题的解决方案,但我只找到了解决方案,以便有人想要使用stdin / stdout / stderr。在我的情况下,我没有尝试,因此找不到修复。以下是我读过的一些链接。

http://bugs.python.org/issue1238747

http://bytes.com/topic/python/answers/851608-using-subprocess-popen-windows-service

以下是代码:

import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os, os.path, sys, string
import cherrypy
import shutil
import subprocess

def CORS():
    cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'

conf = {
    '/': {
        'tools.sessions.on': True,
        'tools.CORS.on' : True,
        'tools.staticdir.root': os.path.abspath(os.getcwd()),
        'request.dispatch': cherrypy.dispatch.MethodDispatcher(),
        'tools.response_headers.on': True,
        'tools.response_headers.headers': [('Content-Type', 'text/plain')]
    }
}

class WebServer(object):
    exposed = True

    def POST(self,TKTcategory,TKTitem,TKTsize,TKTprice,TKTbarcode):
        shutil.copyfile(r"C:\DOHR\ticket_template.ps",r"C:\DOHR\ticket.ps")
        with open(r"C:\DOHR\ticket.ps", "a") as myfile:
            myfile.write("15 15 moveto (" + TKTbarcode + ") (includecheck includetext height=0.3)\n")
            myfile.write("/code128 /uk.co.terryburton.bwipp findresource exec\n")
            myfile.write("/Helvetica findfont 9 scalefont setfont\n")
            myfile.write("/ticket_text (" + TKTcategory + ":" + TKTitem + ") def\n")
            myfile.write("/centered_text_margin 165 2 div def\n")
            myfile.write("/text_width ticket_text stringwidth pop def\n")
            myfile.write("/half_text_width text_width 2 div def\n")
            myfile.write("/final_position centered_text_margin half_text_width sub def\n")
            myfile.write("final_position 55 moveto ticket_text show\n")
            myfile.write("/Helvetica findfont 10 scalefont setfont\n")
            myfile.write("10 40 moveto (Size: " + TKTsize + ") show\n")
            myfile.write("100 40 moveto (Price: $" + TKTprice + ") show\n")
            myfile.write("showpage\n")
            myfile.write("%%EOF\n")

        subprocess.Popen("C:\\Program Files\\GPLGS\\gswin32c.exe -sDEVICE=mswinpr2 -sOutputFile=\"%printer%DYMO LabelWriter 400\" -q -dNOPAUSE -dBATCH C:\\DOHR\\ticket.ps")

class ticket_printer(win32serviceutil.ServiceFramework):

    _svc_name_ = "TGPrintServer"
    _svc_display_name_ = "Web and print server (Ticket Generator)"
    _svc_description_ = "This service implements a CherryPy web server, receives ticket information and builds a corresponding ticket postscript file.  It then prints that file to a local printer via a Ghostscript subprocess call."

    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)
        #exit(0)
        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 = 120000     #120 seconds / 2 minutes
        # This is how long the service will wait to run / refresh itself (see script below)

        while 1:
            cherrypy.tools.CORS = cherrypy.Tool('before_finalize', CORS)
            webapp = WebServer()
            cherrypy.quickstart(webapp, '/', conf)

def ctrlHandler(ctrlType):
    return True

if __name__ == '__main__':
    win32api.SetConsoleCtrlHandler(ctrlHandler, True)
    win32serviceutil.HandleCommandLine(ticket_printer)

0 个答案:

没有答案