简体   繁体   English

用python和py2exe编写的Windows Service上的问题

[英]Problems on Windows Service written in python and py2exe

I've written a service for Windows: 我已经为Windows编写了一项服务:

agentservice.py 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 然后是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也在当前目录中。

agent.conf : agent.conf

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

and my setup.py is: 而我的setup.py是:

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. ./dist目录中有一个agentservice.exe。 And run: 并运行:

agentservice.exe -install 

and everything is fine and the service appears in the Windows service list .it success installed. 一切正常,该服务显示在Windows服务列表中。安装成功。

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. 注意:agent.conf也在当前目录中。

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. 服务的工作目录通常是您的System32目录,安装时的工作目录是项目下的dist目录,并且客户端脚本的工作目录可能是项目的顶层。 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. 在启动时使用os.path.abspath(os.path.dirname(sys.argv[0]))获取脚本目录,然后将os.path.join到路径中。

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. 但是对于您而言,您已经在使用适当的setup.py ,因此您真正想做的是将文件作为数据或其他文件包含在包中,并使用pkg_resources在运行时定位它。 (It's possible that py2exe has its own variation that supersedes the setuptools stuff. If so, use that instead, of course.) py2exe可能有其自己的变体,可以代替setuptools东西。如果是这样,当然可以使用它。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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