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.