[英]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.