Question
I am attempting to start a Python script as a Windows service using pywin32. I can properly install and remove the service, but while installed, its state never changes from "stopped." How can I fix my code so that the service actually runs?
Code
#!/bin/python
import winerror
import win32event
import win32service
import win32serviceutil
SVC_RUN = 1
SVC_REMOVE = 2
class TMP_Service(win32serviceutil.ServiceFramework):
_svc_name_ = "tmp_svc_name"
_svc_display_name_ = "tmp svc disp name"
_svc_reg_class = "tmp.reg_class"
_svc_description_ = "tmp description"
def __init__(self, dut_name):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
def SvcStop(self):
self.reportServiceStatus(win32service.SERVICE_STOP_PENDING)
# I will call reactor.callFromThread(reactor.stop) here to stop the
# FTP and SCP listeners
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
# This infinite loop simulates future behavior of my service. It will
# run a Twisted reactor to handle FTP and TCP network connections.
while True:
pass
win32event.WaitforSingleObject(self.hWaitStop, win32event.INFINITE)
def install_svc():
try:
win32serviceutil.InstallService(
TMP_Service._svc_reg_class,
TMP_Service._svc_name_,
TMP_Service._svc_display_name_,
startType=win32service.SERVICE_AUTO_START)
except win32service.error as e:
if e[0] == winerror.ERROR_SERVICE_EXISTS:
pass # ignore install error if service is already installed
else:
raise
def handle_service(svc):
if svc == SVC_RUN:
try:
win32serviceutil.StartService(TMP_Service._svc_name_)
except win32service.error as e:
if ((e[0] == winerror.ERROR_SERVICE_ALREADY_RUNNING) or
(e[0] == winerror.ERROR_ALREADY_RUNNING_LKG)):
pass # ignore failed start if the service is already running
elif e[0] == winerror.ERROR_SERVICE_DOES_NOT_EXIST:
# if the service is not installed, install it and try again
install_svc()
win32serviceutil.StartService(TMP_Service._svc_name_)
else:
# reraise any other start expection
raise
status = win32serviceutil.QueryServiceStatus(TMP_Service._svc_name_)
print("Service status: {}".format(status[1]))
else:
try:
win32serviceutil.RemoveService(TMP_Service._svc_name_)
except win32service.error as e:
if e[0] == winerror.ERROR_SERVICE_DOES_NOT_EXIST:
pass # ignore failed removal if service is not installed
else:
# reraise any other remove exception
raise
if __name__ == "__main__":
handle_service(SVC_RUN)
Other Details
When I look at the system event logs, I see this error:
Python could not import the service's module
ImportError: No module named tmp
%2: %3
The timestamp for these messages match the times that I tried to run this script.
I have seen this question: Can't start Windows service written in Python (win32serviceutil). Based on the advice there, I have made my code match the suggestion in the top answer there, and made sure that C:\Python27 is in my system path. Neither suggestion made a difference.
The status that is printed is always "2". According to MSDN, this is SERVICE_START_PENDING, which means the service should be starting.
Updated Details
If I change the value of the _svc_reg_class_ attribute to "tmp2.reg_class", then the name of the missing module, as reported in the Windows event log, changes to "tmp2", so this error is related to the _svc_reg_class_ attribute.
In reply to a comment below: I don't think I can capture the full traceback, because my service class is instantiated and used in the pywin32 library code. The offending import doesn't happen anywhere in my code, so there's nothing for me to wrap in a try/except block.
Change the _svc_reg_class = "tmp.reg_class" as shown below.
try:
module_path = modules[TMP_Service.__module__].__file__
except AttributeError:
# maybe py2exe went by
from sys import executable
module_path = executable
module_file = splitext(abspath(module_path))[0]
TMP_Service._svc_reg_class = '%s.%s' % (module_file, TMP_Service.__name__)
Below is the complete modified version of your original code.
#!/bin/python
import winerror
import win32event
import win32service
import win32serviceutil
from sys import modules
from os.path import splitext, abspath
SVC_RUN = 1
SVC_REMOVE = 2
class TMP_Service(win32serviceutil.ServiceFramework):
_svc_name_ = "tmp_svc_name"
_svc_display_name_ = "tmp svc disp name"
_svc_reg_class = "tmp.reg_class"
_svc_description_ = "tmp description"
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)
self.Stop = True
# I will call reactor.callFromThread(reactor.stop) here to stop the
# FTP and SCP listeners
win32event.SetEvent(self.hWaitStop)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.Stop = False
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
# This infinite loop simulates future behavior of my service. It will
# run a Twisted reactor to handle FTP and TCP network connections.
while self.Stop == False:
pass
win32event.WaitforSingleObject(self.hWaitStop, win32event.INFINITE)
def install_svc():
try:
module_path = modules[TMP_Service.__module__].__file__
except AttributeError:
# maybe py2exe went by
from sys import executable
module_path = executable
module_file = splitext(abspath(module_path))[0]
TMP_Service._svc_reg_class = '%s.%s' % (module_file, TMP_Service.__name__)
try:
win32serviceutil.InstallService(
TMP_Service._svc_reg_class,
TMP_Service._svc_name_,
TMP_Service._svc_display_name_,
startType=win32service.SERVICE_AUTO_START)
except win32service.error as e:
if e[0] == winerror.ERROR_SERVICE_EXISTS:
pass # ignore install error if service is already installed
else:
raise
def handle_service(svc):
if svc == SVC_RUN:
try:
win32serviceutil.StartService(TMP_Service._svc_name_)
except win32service.error as e:
if ((e[0] == winerror.ERROR_SERVICE_ALREADY_RUNNING) or
(e[0] == winerror.ERROR_ALREADY_RUNNING_LKG)):
pass # ignore failed start if the service is already running
elif e[0] == winerror.ERROR_SERVICE_DOES_NOT_EXIST:
# if the service is not installed, install it and try again
install_svc()
win32serviceutil.StartService(TMP_Service._svc_name_)
else:
# reraise any other start expection
raise
status = win32serviceutil.QueryServiceStatus(TMP_Service._svc_name_)
print("Service status: {}".format(status[1]))
else:
try:
win32serviceutil.RemoveService(TMP_Service._svc_name_)
except win32service.error as e:
if e[0] == winerror.ERROR_SERVICE_DOES_NOT_EXIST:
pass # ignore failed removal if service is not installed
else:
# reraise any other remove exception
raise
if __name__ == "__main__":
handle_service(SVC_RUN)
Reference: here
Related
I've checked at least a couple of dozen of similar cases to mine and still haven't come up with a solution, I hope someone can shed some light, there's gotta be something I'm missing here.
I'm using Python3.6 to make a Windows service, the service has to run a .exe file if it's not running. Here's the .py:
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import psutil
import subprocess
import os, sys, string, time
import servicemanager
class SLAAgent (win32serviceutil.ServiceFramework):
_svc_name_ = "SLAAgent"
_svc_display_name_ = "SLAAgent"
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.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
self.isAlive = False
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
self._logger.info("Service Is Starting")
main(self)
def main(self):
while self.isAlive:
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
servicemanager.LogInfoMsg("SLAAService has stopped") #For Event Log
break
else:
try:
s = subprocess.check_output('tasklist', shell=True)
if "SLA_Client.exe" in s:
pass
else:
pass
#execfile("SLA_Client.exe") #Execute the script
except:
pass
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(SLAAgent)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(SLAAgent)
I've installed the pywin32 package, added those to the PATH since it was suggested in several solutions, and also copied the .dll from pywin32_system32 to win32
Environment variables
Event Viewer Error
The Event Viewer prints this error every time I run it be it python service.py, or python service.py start, console also prints this:
python SLA_Agent.py
Traceback (most recent call last):
File "SLA_Agent.py", line 56, in <module>
servicemanager.StartServiceCtrlDispatcher()
pywintypes.error: (1063, 'StartServiceCtrlDispatcher', 'The service process
could not connect to the service controller.')
When trying to start the service from the Services tool this is the error that pop ups. I've seen the other error too, the oneabout the service not responding in time.
I've tried compiling it with pyinstaller and nuitka, the errors are the same. I'm unsure as to how to proceed, I've changed the code to fit examples and solutions I've found using google and SO, and have gained little understanding of the hows and whys.
If anyone has faced these issues before, I'd really appreciate the input, other answers haven't helped me so far.
Late edit: fixed the code indentation
This ended up working for me, other than the difference in the code I didn't really do anything special, after a few tries I got to compile with pyinstaller and run service.exe install without issues. There are some extra logging lines that people might not need, but they came in handy when debugging and testing.
Thanks a lot to the everyone who left comments, they were extremely helpful and couldn't have done it without you <3
import win32service, win32serviceutil, win32api, win32con, win32event, win32evtlogutil
import psutil
import subprocess
import os, sys, string, time, socket, signal
import servicemanager
class Service (win32serviceutil.ServiceFramework):
_svc_name_ = "Service"
_svc_display_name_ = "Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('Service Initialized.')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg))
def sleep(self, sec):
win32api.Sleep(sec*1000, True)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
self.log('Service has stopped.')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.log('Service is starting.')
self.main()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
except Exception as e:
s = str(e);
self.log('Exception :'+s)
self.SvcStop()
def stop(self):
self.runflag=False
try:
#logic
except Exception as e:
self.log(str(e))
def main(self):
self.runflag=True
while self.runflag:
rc = win32event.WaitForSingleObject(self.stop_event, 24*60*60)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
self.log("Service has stopped")
break
else:
try:
#logic
except Exception as e:
self.log(str(e))
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(Service)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(Service)
I have created a program in Python. Its task is to check some logs and it will perform some activity.
Reg_Version.py
class RegisterService:
.
.
def performAction(self):
self.__logFileSizeCheck()
self.__getHostName()
self.__deteleFiles()
self.__createFiles()
.
.
class Service(win32serviceutil.ServiceFramework):
_svc_name_ = '_test'
_svc_display_name_ = '_Service Template'
def __init__(self, *args):
win32serviceutil.ServiceFramework.__init__(self, *args)
self.log('init')
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg))
def sleep(self, sec):
win32api.Sleep(sec*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, x:
self.log('Exception : %s' % x)
self.SvcStop()
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.log('stopping')
self.stop()
self.log('stopped')
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
# to be overridden
def start(self): pass
# to be overridden
def stop(self): pass
def instart(cls, name, display_name=None, stay_alive=True):
cls._svc_name_ = name
cls._svc_display_name_ = display_name or name
cls._svc_description_ = "Register service if it fails to register."
try:
module_path=modules[cls.__module__].__file__
except AttributeError:
# maybe py2exe went by
from sys import executable
module_path=executable
module_file = splitext(abspath(module_path))[0]
cls._svc_reg_class_ = '%s.%s' % (module_file, cls.__name__)
if stay_alive: win32api.SetConsoleCtrlHandler(lambda x: True, True)
try:
win32serviceutil.InstallService(
cls._svc_reg_class_,
cls._svc_name_,
cls._svc_display_name_,
startType = win32service.SERVICE_AUTO_START
)
print 'Install ok'
win32serviceutil.StartService(
cls._svc_name_
)
print 'Start ok'
except Exception, x:
print str(x)
class Test(Service):
def start(self):
self.serv = RegisterService() #<---RegisterService() is my created class
self.runflag=True
while self.runflag:
self.serv.performAction() #<---The method is called here
self.sleep(60)
self.log("Service is alive")
def stop(self):
self.runflag=False
self.log("Service is stopped")
instart(Test, 'Myservice', 'MyServerTest_1')
The script runs well when executed from cmd prompt
C:\Windows\system32>python "C:\Users\Arijit\Desktop\New folder (2)\Reg_Version.py"
Install ok
Start ok
Up to here everything works well.
Now I want it to create an executable windows service so that I can deploy the program to other systems. After googling I came to know that it can be done using pyinstaller / py2exe . I first used pyinstaller and it converted to a single executable package. After executing the .exe as admin, the service showed on the services.msc but it didn't start not even when clicking the start option. I check the eventvwr and found the following error
error 1053 the service did not respond to the start or control request in a timely fashion
I tried with py2exe, and getting the same issue. The service is getting install but not getting started.
I referred this link
Python Windows service pyinstaller executables error 1053
but it didn't solve.
I'm developing a Python daemon responsible for converting multimedia files to .mp4 format.
The idea is to have the daemon running and, whenever the user requires, I add the desired video to a Queue and a thread eventually gets the video from the queue and calls Handbrake via Subprocess in order to do the conversion. For simplicity's sake, I'm using only one thread at the moment.
Here's my code.
First, the daemon (server.py, adapted from Kris Johnson's post here):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys
import os.path
import logging.config
import SocketServer
import optparse
import resource
import socket, tempfile
import time
from threadedqueue import QueueServer
version = '0.1'
SERVER_PORT=6666
SERVER_SOCKET='server_socket'
SERVER_TYPE=SocketServer.UnixStreamServer
ServerBase = SERVER_TYPE
if ServerBase == SocketServer.UnixStreamServer:
server_address = os.path.join(tempfile.gettempdir(), SERVER_SOCKET)
SERVER_LOG=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'convertCentral.log')
logging.basicConfig(format='[%(asctime)s.%(msecs).03d] %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=SERVER_LOG, level=logging.INFO)
class RequestHandler(SocketServer.StreamRequestHandler):
"""Request handler
An instance of this class is created for each connection made
by a client. The Server class invokes the instance's
setup(), handle(), and finish() methods.
The template implementation here simply reads a single line from
the client, breaks that up into whitespace-delimited words, and
then uses the first word as the name of a "command." If there is
a method called "do_COMMAND", where COMMAND matches the
commmand name, then that method is invoked. Otherwise, an error
message is returned to the client.
"""
def handle(self):
"""Service a newly connected client.
The socket can be accessed as 'self.connection'. 'self.rfile'
can be used to read from the socket using a file interface,
and 'self.wfile' can be used to write to the socket using a
file interface.
When this method returns, the connection will be closed.
"""
# Read a single request from the input stream and process it.
request = self.rfile.readline()
if request:
self.server.log('request %s: %s',
self.connection.getpeername(), request.rstrip())
try:
self.process_request(request)
except Exception, e:
self.server.log('exception: %s' % str(e))
self.wfile.write('Error: %s\n' % str(e))
else:
self.server.log('error: unable to read request')
self.wfile.write('Error: unable to read request')
def process_request(self, request):
"""Process a request.
This method is called by self.handle() for each request it
reads from the input stream.
This implementation simply breaks the request string into
words, and searches for a method named 'do_COMMAND',
where COMMAND is the first word. If found, that method is
invoked and remaining words are passed as arguments.
Otherwise, an error is returned to the client.
"""
words = request.split()
if len(words) == 0:
self.server.log('error: empty request')
self.wfile.write('Error: empty request\n')
return
command = words[0]
args = words[1:]
methodname = 'do_' + command
if not hasattr(self, methodname):
self.server.log('error: invalid command')
self.wfile.write('Error: "%s" is not a valid command\n' % command)
return
method = getattr(self, methodname)
method(*args)
def do_stop(self, *args):
self.wfile.write('Stopping server\n')
self.server.stop()
"""Process an 'echo' command"""
def do_echo(self, *args):
self.wfile.write(' '.join(args) + '\n')
"""Process a 'convert' command"""
def do_convert(self, video):
self.wfile.write('Converting %s\n' % (video))
try:
self.server.addVideo(video)
except Exception as e:
logging.info("ERROR: %s" % e)
class Server(ServerBase):
def __init__(self, server_address):
self.__daemonize()
self.pool = QueueServer()
if ServerBase == SocketServer.UnixStreamServer:
# Delete the socket file if it already exists
if os.access(server_address, 0):
os.remove(server_address)
ServerBase.__init__(self, server_address, RequestHandler)
def addVideo(self, video):
self.pool.add(video)
def log(self, format, *args):
try:
message = format % args
logging.info("%s" % message)
except Exception, e:
print str(e)
def serve_until_stopped(self):
self.log('started')
self.__stopped = False
while not self.__stopped:
self.handle_request()
self.log('stopped')
def stop(self):
self.__stopped = True
def __daemonize(self):
UMASK = 0
WORKDIR = '/'
MAXFD = 1024
if hasattr(os, 'devnull'):
REDIRECT_TO = os.devnull
else:
REDIRECT_TO = '/dev/null'
try :
if os.fork() != 0:
os._exit(0)
os.setsid()
if os.fork() != 0:
os._exit(0)
os.chdir(WORKDIR)
os.umask(UMASK)
except OSError, e:
self.log('exception: %s %s', e.strerror, e.errno)
raise Exception, "%s [%d]" % (e.strerror, e.errno)
except Exception, e:
self.log('exception: %s', str(e))
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if maxfd == resource.RLIM_INFINITY:
maxfd = MAXFD
for fd in range(0, maxfd):
try:
os.close(fd)
except OSError:
pass
os.open(REDIRECT_TO, os.O_RDWR)
os.dup2(0, 1)
os.dup2(0, 2)
""" Run a server as a daemon """
def run_server(options, args):
print("convertCentral running on %s" % server_address)
svr = Server(server_address)
svr.serve_until_stopped()
svr.server_close()
"""Send request to the server and process response."""
def do_request(options, args):
if ServerBase == SocketServer.UnixStreamServer:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Send request
s.connect(server_address)
s.sendall(' '.join(args) + '\n')
# Print response
sfile = s.makefile('rb')
line = sfile.readline()
while line:
print line,
line = sfile.readline()
#######################################################################
#######################################################################
if __name__ == '__main__':
optparser = optparse.OptionParser(usage=usage,
version=version)
(options, args) = optparser.parse_args()
if len(args) == 0:
optparser.print_help()
sys.exit(-1)
if args[0] == 'start':
run_server(options, args[1:])
else:
do_request(options, args)
Then, the queue (threadedqueue.py - sorry about the name, not feeling particularly creative):
#! /usr/bin/python
# -*- coding: utf-8 -*-
import os, time, threading, psutil, resource, logging, subprocess as sp, sys
from Queue import Queue
from threading import Thread
SERVER_LOG=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'convertCentral.log')
logging.basicConfig(format='[%(asctime)s.%(msecs).03d] %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=SERVER_LOG, level=logging.INFO)
class QueueServer(object):
current_video_queue = Queue(maxsize=0)
N_WORKER_THREADS = 1
counter = 0
def __init__(self):
logging.info("[QueueServer] Initializing the video conversion queue")
for i in range(self.N_WORKER_THREADS):
logging.info("Firing thread")
t = Thread(target=self.worker)
t.daemon = True
t.start()
''' Converts the video using Handbrake via subprocess'''
def convertVideo(self, video):
logging.info("Now converting %s" % video)
fileName, fileExtension = os.path.splitext(video)
payload = "nice -n 15 HandBrakeCLI -i %s -e x264 -q 15 -o %s.mp4" % (video, fileName)
pr = sp.Popen(payload, shell=True, stdout=open('/dev/null', 'w'), stderr=sp.STDOUT)
logging.info('Started handbrake')
pr.wait()
logging.info("EXIT CODE: %s " % pr.returncode)
self.counter = self.counter + 1
logging.info("Conversion's done. %d" % self.counter)
''' A worker thread '''
def worker(self):
while True:
logging.info("Getting one")
item = self.current_video_queue.get()
logging.info("Firing conversion: %s" % item)
self.convertVideo(item)
self.current_video_queue.task_done()
logging.info("All done")
''' Adds a video to the video conversion queue '''
def add(self, video):
logging.info("* Adding %s to the queue" % video)
self.current_video_queue.put(video)
logging.info("* Added %s to the queue" % video)
time.sleep(3)
Here's the deal: if I run the threadedqueue on its own, it works great.
However, if I run it using server.py, the conversion never happens because Handbrake crashes.
Here are the logs:
Hal#ubuntu:~/Desktop/convertCentral$ python server.py start
convertCentral running on /tmp/server_socket
Hal#ubuntu:~/Desktop/convertCentral$ python server.py convert UNKNOWN_PARAMETER_VALUE.WMV
[2014-04-17 18:05:44.793] request : convert UNKNOWN_PARAMETER_VALUE.WMV
Converting UNKNOWN_PARAMETER_VALUE.WMV
[2014-04-17 18:05:44.793] * Adding UNKNOWN_PARAMETER_VALUE.WMV to the queue
[2014-04-17 18:05:44.793] * Added UNKNOWN_PARAMETER_VALUE.WMV to the queue
[2014-04-17 18:05:44.793] Firing conversion: UNKNOWN_PARAMETER_VALUE.WMV
[2014-04-17 18:05:44.794] Now converting UNKNOWN_PARAMETER_VALUE.WMV
[2014-04-17 18:05:44.796] Started handbrake
[2014-04-17 18:05:45.046] Exit code: 0
[2014-04-17 18:05:45.046] Conversion's done. 1
[2014-04-17 18:05:45.046] All done
[2014-04-17 18:05:45.047] Getting one
I logged the subprocess's output to a file.
Here's what I got:
[18:05:44] hb_init: starting libhb thread
HandBrake 0.9.9 (2013051800) - Linux x86_64 - http://handbrake.fr
4 CPUs detected
Opening UNKNOWN_PARAMETER_VALUE.WMV...
[18:05:44] hb_scan: path=UNKNOWN_PARAMETER_VALUE.WMV, title_index=1
libbluray/bdnav/index_parse.c:162: indx_parse(): error opening UNKNOWN_PARAMETER_VALUE.WMV/BDMV/index.bdmv
libbluray/bdnav/index_parse.c:162: indx_parse(): error opening UNKNOWN_PARAMETER_VALUE.WMV/BDMV/BACKUP/index.bdmv
libbluray/bluray.c:1725: nav_get_title_list(UNKNOWN_PARAMETER_VALUE.WMV) failed (0x7fd44c000900)
[18:05:44] bd: not a bd - trying as a stream/file instead
libdvdnav: Using dvdnav version 4.1.3
libdvdread: Encrypted DVD support unavailable.
libdvdread: Can't stat UNKNOWN_PARAMETER_VALUE.WMV
No such file or directory
libdvdnav: vm: failed to open/read the DVD
[18:05:44] dvd: not a dvd - trying as a stream/file instead
[18:05:44] hb_stream_open: open UNKNOWN_PARAMETER_VALUE.WMV failed
[18:05:44] scan: unrecognized file type
[18:05:44] libhb: scan thread found 0 valid title(s)
No title found.
HandBrake has exited.
So, we can attest that the script can indeed fire up Handbrake, but the logs indicate that the Handbrake won't recognize the file format and dies on the spot. Again, this doesn't happen if I run the threadedqueue.py script on its own.
I'm guessing that Handbrake is not loading its libraries somehow.
Is this the reason the code won't work? How can I get Handbrake to work?
(darned browser lost my previous answer, hope this does not become a dup)
Both of these errors Can't stat UNKNOWN_PARAMETER_VALUE.WMV and
open UNKNOWN_PARAMETER_VALUE.WMV failed suggest file-not-found errors, BUT it does look like the file name is getting passed through to the handbrake command line.
So in order to be sure that the right files are being used: In the python code convert whatever filenames the user provides to server.py into absolute path names (see os.path.*). Use those absolute path names everywhere (esp. in the handbrake command/Popen)
I have problem with solution that was working very good and suddenly it stopped to do so. I wrote server/client scripts and modules to make a SOAP connection type for my application.
Here is my server code :
import os
import rsglobal
import signal
import soaplib
from soaplib.core.service import rpc, DefinitionBase, soap
from soaplib.core.model.primitive import String, Integer
from soaplib.core.server import wsgi
from soaplib.core.model.clazz import Array
try:
import psycopg
except:
import psycopg2 as psycopg
import rssql
LogFile = "serwer_soap.log"
#-##############################################################################
#-- SOAP SERVER CLASS
#-##############################################################################
class AnakondaSOAPServer(DefinitionBase):
#-##############################################################################
#-- SOAP FUNCTIONS
#-##############################################################################
#soap(String,Integer,_returns=Array(String))
def say_hello(self,name,times):
results = []
for i in range(0,times):
results.append('Hello, %s'%name)
return results
#soap(String,String,_returns=String)
def ConnectToBase(self,name,passwd):
global PolSQL
try:
stat = 'OK'
dane=[]
PolSQL=rssql.RSSQL()
if PolSQL.ConnectToSQL(name,passwd,'127.0.0.1',5432,'','databasename')==1:
stat = u'Connection Error'
SQL='SELECT * FROM table1;'
stat,dane,dump,dump=PolSQL.Execute(SQL,3)
except Exception,e:
return u'Connection Error '+str(e)
return stat+' '+str(dane)
#soap(_returns=String)
def GiveData(self):
global PolSQL
try:
stat = 'OK'
dane=[]
SQL='SELECT * FROM table1;'
stat,dane,dump,dump=PolSQL.Execute(SQL,3)
except Exception,e:
return u'Data getting error '+str(e)
return stat+' '+str(dane)
#------------------------------------------
# ADMINISTRATIVE FUNCTIONS
#------------------------------------------
def SetDefaultData(self):
self._oldHupHandler = signal.SIG_DFL
self._oldAlarmHandler = signal.SIG_DFL
self._oldTermHandler = signal.SIG_DFL
self._childProcess = None
self.PolSQL = None
#-------------------------------------------------------------------------------
def _OnSIGALRM(self, sig, frame):
pass
#-------------------------------------------------------------------------------
def _OnSIGHUP(self, sig, frame):
if self._childProcess:
os.kill(self._childProcess, signal.SIGHUP)
else:
pass
#-------------------------------------------------------------------------------
def _OnSIGTERM(self, sig, frame):
pass
#-------------------------------------------------------------------------------
def _exit(self, status):
if self.PolSQL:
self.PolSQL.DisconnectSQL()
if status:
rsglobal.Log(u"SOAP - finishing : "+str(status), 1)
os._exit(status)
#-------------------------------------------------------------------------------
def StartSOAPServer(self, dbspec,HostSOAP,PortSOAP):
import os
self.dbspec = dbspec
childPID = os.fork()
if childPID:
self._childProcess = childPID
return childPID
else:
try:
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
if LogFile:
rsglobal.LogFile = LogFile
self._oldHupHandler = signal.signal(signal.SIGHUP, lambda x, y: self._OnSIGHUP(x, y))
self._oldAlarmHandler = signal.signal(signal.SIGALRM, lambda x, y: self._OnSIGALRM(x, y))
self._oldTermHandler = signal.signal(signal.SIGTERM, lambda x, y: self._OnSIGTERM(x, y))
self.PolSQL = SQLConnect(self.dbspec)
# running SOAP server
from wsgiref.simple_server import make_server
ServiceSoap = soaplib.core.Application([AnakondaSOAPServer],'AnakSOAP',name='AnakSOAP')
WSGI = wsgi.Application(ServiceSoap)
Serwer = make_server(HostSOAP, int(PortSOAP), WSGI)
Serwer.serve_forever()
except Exception, exc:
rsglobal.ZapiszDoLogow(u"Server SOAP Error : "+str(exc), 2)
self._exit(1)
#-------------------------------------------------------------------------------
def StopSOAPServer(self):
if self._childProcess:
os.kill(self._childProcess, signal.SIGTERM)
#-##################################################################
#-### - This is main SOAP server object used in other modules
SerwerSOAP = AnakondaSOAPServer()
SerwerSOAP.SetDefaultData()
#-##############################################################################
#-## ADDITIONAL FUNCTIONS
#-##############################################################################
def SQLConnect(dbspec):
# creates connection to database
PolSQL = rssql.RSSQL()
dbuser, dbpass, dbhost, dbport, dbase = dbspec
if PolSQL.PolaczZSQL(dbuser, dbpass, dbhost, dbport, None, Baza=dbase):
return False
else:
return PolSQL
My client code (which just tests server) is like this :
from suds.client import Client
hello_client = Client('http://128.1.2.3:1234/AnakondaSOAPServer?wsdl')
hello_client.options.cache.clear()
result = hello_client.service.ConnectToBase("username", "password")
print 'Result1',result
result = hello_client.service.GiveData()
print 'Result2',result
Earlier in my main application i use function StartSOAPServer with proper parameters and it's waiting for connections. I can see it with netstat on good adress and port.
After running client script i get :
Traceback (most recent call last):
File "./testsoapclient.py", line 8, in <module>
hello_client = Client('http://128.1.2.3:1234/AnakondaSOAPServer?wsdl')
File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/client.py", line 112, in __init__
self.wsdl = reader.open(url)
File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/reader.py", line 152, in open
d = self.fn(url, self.options)
File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 158, in __init__
self.resolve()
File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 207, in resolve
c.resolve(self)
File "/usr/local/lib/python2.6/dist-packages/suds-0.4-py2.6.egg/suds/wsdl.py", line 494, in resolve
raise Exception("msg '%s', not-found" % op.input)
Exception: msg 's0:ConnectToBase', not-found
Earlier i had problem with visibility of functions after creating a SOAP connection. Solution was to clear a cache. Now i can't even create it.
I use python 2.6, and lately my main app was transfered from 2.4 to 2.6. It's the only difference i can think of.
I tried manipulate with soaplib.core.Application definition, but it didn't work.
Please help :)
I managed to overcome the problems and it's working again.
First thing that repairs situation is splitting server into 2 classes - one to create object and run SOAPServer and second - SOAPServer which contains only definitions of functions.
Even after doing this changes i had bad results. I found out, that damaged structure of server definition hides in /tmp/suds directory (and that is why it was working while having damaged code before). Deleting this files allowed to refresh this structure and all scripts started to work again.
I am trying to write dbus server where I want to run some external shell program (grep here) to do the job.
when I do:
prompt$ server.py
then:
prompt$ client.py # works fine, ie. runs grep command in child process.
prompt$ client.py # ..., but second invocation produces following error message:
DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.example.ExampleService was not provided by any .service files
I am stuck. Are You able to help me?
here is server.py (client.py thereafter):
import gtk, glib
import os
import dbus
import dbus.service
import dbus.mainloop.glib
import subprocess
messages_queue=list()
grep_pid=0
def queue_msg(message):
global messages_queue
messages_queue.append(message)
return
def dequeue_msg():
global messages_queue,grep_pid
if grep_pid != 0:
try:
pid=os.waitpid(grep_pid,os.P_NOWAIT)
except:
return True
if pid[0] == 0:
return True
grep_pid=0
if len(messages_queue) == 0:
return True
else:
tekst=messages_queue.pop(0)
cmd="grep 'pp'"
print cmd
#works fine, when I do return here
#return True
grep_pid=os.fork()
if grep_pid != 0:
return True
os.setpgid(0,0)
pop=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE)
pop.stdin.write(tekst)
pop.stdin.close()
pop.wait()
exit(0)
class DemoException(dbus.DBusException):
_dbus_error_name = 'org.example.Exception'
class MyServer(dbus.service.Object):
#dbus.service.method("org.example.ExampleInterface",
in_signature='', out_signature='')
def QueueMsg(self):
queue_msg("ppppp")
#dbus.service.method("org.example.ExampleInterface",
in_signature='', out_signature='')
def Exit(self):
mainloop.quit()
from dbus.mainloop.glib import threads_init
if __name__ == '__main__':
glib.threads_init()
threads_init()
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
session_bus = dbus.SessionBus()
name = dbus.service.BusName("org.example.ExampleService", session_bus)
object = MyServer(session_bus, '/My')
glib.timeout_add_seconds(1, dequeue_msg)
mainloop = glib.MainLoop()
print "Running example service."
mainloop.run()
now client.py:
import sys
from traceback import print_exc
import dbus
def main():
bus = dbus.SessionBus()
try:
remote_object = bus.get_object("org.example.ExampleService",
"/My")
except dbus.DBusException:
print_exc()
sys.exit(1)
iface = dbus.Interface(remote_object, "org.example.ExampleInterface")
iface.QueueMsg()
if sys.argv[1:] == ['--exit-service']:
iface.Exit()
if __name__ == '__main__':
main()
You usually get this error message when you try to access a service that is no longer available. Check if your server is still running.
You can use d-feet to debug your dbus connections.
The error message about the missing .service file means that you need to create a service file in dbus-1/services.
For example:
# /usr/local/share/dbus-1/services/org.example.ExampleService.service
[D-BUS Service]
Name=org.example.ExampleService
Exec=/home/user1401567/service.py
A lot of tutorials don't include this detail (maybe .service files didn't use to be required?) But, at least on Ubuntu 12.04, dbus services can't be connected to without it.