用python和py2exe编写的Windows服务问题

时间:2014-12-18 06:24:57

标签: python windows service py2exe

我为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)

然后 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

注意:agent.conf也在当前目录中。

agent.conf

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

我的 setup.py 是:

from distutils.core import setup
import py2exe
import sys

sys.argv.append("py2exe")

setup(service = ["agentservice"])
我跑完后

 python setup.py

./dist目录中有agentservice.exe。并运行:

agentservice.exe -install 

一切都很好,服务出现在Windows服务列表中。安装成功。

但令我困惑的是:为什么我的服务无法正常启动和停止? 我的代码中有任何错误吗?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

  

注意:agent.conf也在当前目录中。

如何?当前目录是您启动程序时所在的目录。服务的工作目录通常是您的System32目录,您安装时的工作目录是项目下的dist目录,并且可能是客户端脚本的工作目录是项目的最高级别。除非您创建了硬链接/联结,否则该文件不会在所有三个位置。

如果要查找脚本目录中的文件,则必须明确地执行此操作。您可以在启动时将当前目录更改为脚本的目录,或者将服务配置为从脚本的目录而不是默认位置运行 - 或者,更好的是,您可以忽略当前的工作目录;在启动时使用os.path.abspath(os.path.dirname(sys.argv[0]))获取脚本目录,然后在路径中获取os.path.join

但在您的情况下,您已经使用了正确的setup.py,因此您真正想要做的是将文件作为数据或附加文件包含在您的包中并使用pkg_resources在运行时找到它。 (py2exe可能有自己的变体取代setuptools的东西。如果是这样,当然可以使用它。)