简体   繁体   中英

Problems on Windows Service written in python and py2exe

I've written a service for Windows:

agentservice.py

import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import agent

class AgentService(win32serviceutil.ServiceFramework):
    _svc_name_ = "AgentService"
    _svc_display_name_ = "AgentService"
    _svc_deps_ = ["EventLog"]
    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcRun(self):
        import servicemanager
        agent.verify()
        # Write a 'started' event to the event log...
        win32evtlogutil.ReportEvent(self._svc_name_,servicemanager.PYS_SERVICE_STARTED,0,     servicemanager.EVENTLOG_INFORMATION_TYPE,(self._svc_name_, ''))

        # wait for beeing stopped...
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

        # and write a 'stopped' event to the event log.
        win32evtlogutil.ReportEvent(self._svc_name_,servicemanager.PYS_SERVICE_STOPPED,0,
servicemanager.EVENTLOG_INFORMATION_TYPE,(self._svc_name_, ''))

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)


if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AgentService)

then agent.py

import os
import socket
import time
import json
import platform
PLATFORM = platform.system()
import uuid
import sys


HOST = 'highwe.net'
PORT = 8302
USERKEY = None


def getHoldHost():
    hold_host = os.environ.get('HOLDHOST')
    if hold_host is None:
        return HOST
    return hold_host
HOST = getHoldHost()


def macAddress():
    return ':'.join(['{:02x}'.format((uuid.getnode() >> i) & 0xff) for i in range(0, 8 * 6, 8)][::-1])


def getRelease():
     '''Get OS info'''
    release = ''
    if PLATFORM == 'Windows':
        release = osAction("ver").decode('gbk')
    return release


def getExpInfo(just_info=False):
    '''Get Exception'''
    import traceback
    if just_info:
        info = sys.exc_info()
        return info[0].__name__ + ':' + str(info[1])
    else:
        return traceback.format_exc()


def osAction(command):
    '''
    run command
    '''
    try:
        p = os.popen(command)
        content = p.read()
        p.close()
    except Exception:
        content = 'djoin_error:' + getExpInfo(True)
    return content

def socketAgent():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((HOST, PORT))
    return sock

def diskMon():
    mon_data = None
    if PLATFORM == 'Windows':
        disk = osAction("wmic logicaldisk get caption, size, freespace, drivetype")
        mon_data = dict(disk=disk)
    else:
        pass
    return mon_data

def send():
    mac = macAddress()
    release = getRelease()
    try:
        sock = socketAgent()
        while True:
            if disk:
                message = json.dumps(dict(user_key=USERKEY, platform=PLATFORM, mac=mac, release=release, mon_data=disk, type="disk")) + '\u7ed3\u675f'
                sock.send(message)
                print '%s send disk' % PLATFORM
            time.sleep(5)
    except socket.error:
        error_info = getExpInfo(True)
        print HOST
        print error_info
        time.sleep(5)
        send()

def verify():
    global USERKEY
    with open('agent.conf', 'r') as f:
        out_data = f.read()
        USERKEY = json.loads(out_data).get('user_key')
    #print 'start...'
    agentPid = os.getpid()
    writePid(agentPid)
    send()

def writePid(pid):
    pid = str(pid)
    with open('pid.config','w') as f:
        f.write("%s\n" % pid)

if __name__ == '__main__':
    pass

Note: agent.conf is also in current directory.

agent.conf :

{"user_key": "cd7eab88-3055-4b1d-95a4-2ad80731d226"}

and my setup.py is:

from distutils.core import setup
import py2exe
import sys

sys.argv.append("py2exe")

setup(service = ["agentservice"])

after I am run :

 python setup.py

there is a agentservice.exe in ./dist directory. And run:

agentservice.exe -install 

and everything is fine and the service appears in the Windows service list .it success installed.

But what confused me is : why my service can't start and stop normally? Is there any bugs in my code?

Any help would be greatly appreciated.

Note: agent.conf is also in current directory.

How? The current directory is the directory you're in when you start the program. The working directory for a service is usually your System32 directory, the working directory at the time you install is the dist directory under your project, and presumably the working directory for the client script is the top level of your project. Unless you've created a hardlink/junction, the file isn't in all three places.

If you want to find a file that's in the script's directory, you have to do that explicitly. You can change the current directory to the script's directory at startup, or configure the service to run from the script's directory instead of the default location—or, better, you can ignore the current working directory; get the script directory at startup with os.path.abspath(os.path.dirname(sys.argv[0])) and then os.path.join that to the path.

But in your case, you're already using a proper setup.py , so what you really want to do is include the file as a data or extra file in your package and use pkg_resources to locate it at runtime. (It's possible that py2exe has its own variation that supersedes the setuptools stuff. If so, use that instead, of course.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM