我创建了一个python应用程序,该应用程序可以作为服务运行,并具有系统任务栏图标(适用于Windows)。我将wxPython用作将主程序作为线程调用的包装程序。问题是当我将该程序作为服务启动时,主程序运行了,但是未创建系统任务栏图标。
我已经读过,将系统任务栏图标创建为Windows服务不是很理想,但是再次发现有关该主题的信息冲突。
这是我的代码:
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
import sys,os,time
#// Wx
import wx.adv
import wx #pip install wxpython
from wx.lib.embeddedimage import PyEmbeddedImage
from threading import Thread
#from pubsub import pub #pip install PyPubSub
TRAY_TOOLTIP = 'test5'
get_python_logo = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAA4AAAATCAIAAAAvYqvDAAAAA3NCSVQICAjb4U/gAAACjUlE"
"QVQokQXBW4/bRBgA0G++ufhux068abaQUvUmASovCHhC/HOe+oCQkFYVSKjbVQXsshuycXwb"
"ezw3ziH+6idvUJuAh/VvVzd5eRnnZZSEd7efpDx+9/3bqbnjTlL0CGb2oAk6QmxepFkeE2LP"
"5+N6U4QRs1NvnaKUEOoRqEXugWhtZLEKt0/K9ToLAnJRr7JEDGNjnSTcADUMGAWky2SHvmO8"
"IkkS8OiCI01FnKVSdWnIgFBvFvSGg4+8j8bJAY3BBoApj9bgwizbeh8xkQGJnAtRQ+BJyKKc"
"iixbbZ1DWKzSRC1OJOXiqYXAeO5pwJRDpeys7eSBRInUYLRarAGvs1SchplwSATEgrNOlvPs"
"hgnPHb3Ylf0EljBPnLMRE+Gxib0TJuEkT5jsv3z1w4+Q1Nfv3lPyYplkulpruwBZ5DC//erZ"
"k69fwPnhz19/YY4I1/QY7F5+8y3Eu+JlAMDAG6AWpkfABaax/fcxiHKG0c0fH2/Ebb17+gb6"
"CnnqgRFOEJbT6bbM+afr983hr/3TLbu8hA8f/0Yzns+2H3FxQVHVSs9q7gJhtVqiqGvxfrNZ"
"ITNtTOTr/Trmc5l4XJp1CqgbNx3rgk6nf54/r8vEE92wpW+dHP0sz3cd0NXcqhB8wvixeZxz"
"1h4OMG5xnuSpYVm8qUI7n2ZhuHeiCmOxsIt4M4SV792zej89DIUoC5oysF5Q1Mvw+RdvnKsN"
"xNp5RNx/9kqOD+vX9eHqXcgpsQYBVFZQzx/vTx/u207s9hNTPUw83RRVebj+edS/F5XFAhjo"
"AVCj0NapblTpeWjGkVOm1GRVi7QNMgU4AY0QnKEMw1AgopTzuem7VqrZ9d18/K9FEuZZ5ZwD"
"5/4H45tv6Xt4MTIAAAAASUVORK5CYII=")
def create_menu_item(menu, label, func):
item = wx.MenuItem(menu, -1, label)
menu.Bind(wx.EVT_MENU, func, id=item.GetId())
menu.Append(item)
return item
class ProgramThread(Thread):
"""Worker Thread Class."""
def __init__(self):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.setDaemon(True)
self.start() # start the thread
def run(self):
"""Run Worker Thread."""
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(AppServerSvc)
servicemanager.StartServiceCtrlDispatcher()
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "test5"
_svc_display_name_ = "test5"
_svc_description_name_ = "test5"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
def SvcStop(self):
#wx.CallAfter(pub.sendMessage, "exit", event="exit")
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,'Attemping to Start the Service.'))
self.main()
def main(self):
while True:
print 1
class TaskBarIcon(wx.adv.TaskBarIcon):
def __init__(self, frame):
self.frame = frame
super(TaskBarIcon, self).__init__()
self.set_icon(get_python_logo.GetIcon())
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)
# create a pubsub receiver
#pub.subscribe(self.on_exit, "exit")
ProgramThread()
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu, 'Site', self.on_hello)
menu.AppendSeparator()
create_menu_item(menu, 'Exit', self.on_exit)
return menu
def set_icon(self, path):
print "set icon"
icon = wx.Icon(path)
self.SetIcon(icon, TRAY_TOOLTIP)
def on_left_down(self, event):
print ('Tray icon was left-clicked.')
def on_hello(self, event):
print ('Hello, world!')
def on_exit(self, event):
wx.CallAfter(self.Destroy)
self.frame.Close()
class App(wx.App):
def OnInit(self):
frame=wx.Frame(None)
self.SetTopWindow(frame)
TaskBarIcon(frame)
return True
# Run the program
if __name__ == "__main__":
#// Whether called by user or service manager
if len(sys.argv) == 1:
app = App(False)
app.MainLoop()
else:
win32serviceutil.HandleCommandLine(AppServerSvc)