我为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服务列表中。安装成功。
但令我困惑的是:为什么我的服务无法正常启动和停止? 我的代码中有任何错误吗?
非常感谢任何帮助。
答案 0 :(得分:0)
注意:agent.conf也在当前目录中。
如何?当前目录是您启动程序时所在的目录。服务的工作目录通常是您的System32目录,您安装时的工作目录是项目下的dist
目录,并且可能是客户端脚本的工作目录是项目的最高级别。除非您创建了硬链接/联结,否则该文件不会在所有三个位置。
如果要查找脚本目录中的文件,则必须明确地执行此操作。您可以在启动时将当前目录更改为脚本的目录,或者将服务配置为从脚本的目录而不是默认位置运行 - 或者,更好的是,您可以忽略当前的工作目录;在启动时使用os.path.abspath(os.path.dirname(sys.argv[0]))
获取脚本目录,然后在路径中获取os.path.join
。
但在您的情况下,您已经使用了正确的setup.py
,因此您真正想要做的是将文件作为数据或附加文件包含在您的包中并使用pkg_resources
在运行时找到它。 (py2exe
可能有自己的变体取代setuptools
的东西。如果是这样,当然可以使用它。)