未显示Python Windows服务托盘图标
我使用HelpSocketServer编写了一个基本的Python脚本。然后,用代码将其包装成Windows服务,并为托盘图标添加一个功能。 将脚本安装为服务。当我这样运行它时:未显示Python Windows服务托盘图标,python,windows,windows-services,pywin32,win32gui,Python,Windows,Windows Services,Pywin32,Win32gui,我使用HelpSocketServer编写了一个基本的Python脚本。然后,用代码将其包装成Windows服务,并为托盘图标添加一个功能。 将脚本安装为服务。当我这样运行它时: test.py debug 服务启动,工作完美,最重要的是,图标出现在托盘中 但当我跑步时: test.py start 脚本无法启动。如果通过控制台MMC运行,将显示以下消息: 没有额外的信息 在花了一些时间进行代码研究后,我在show()方法中发现了这一行的罪过: win32gui.Shell_NotifyI
test.py debug
服务启动,工作完美,最重要的是,图标出现在托盘中
但当我跑步时:
test.py start
脚本无法启动。如果通过控制台MMC运行,将显示以下消息:
没有额外的信息
在花了一些时间进行代码研究后,我在show()
方法中发现了这一行的罪过:
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid)
TrayIcon功能:
class Taskbar:
icoimage = None
hinst = win32api.GetModuleHandle(None)
def __init__(self):
self.visible = 0
message_map = {
win32con.WM_DESTROY: self.onDestroy,
win32con.WM_USER+20 : self.onTaskbarNotify,
}
# Register the Window class.
wc = win32gui.WNDCLASS()
hinst = wc.hInstance = win32api.GetModuleHandle(None)
wc.lpszClassName = "PythonTaskbarDemo"
wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
wc.hCursor = win32gui.LoadCursor( 0, win32con.IDC_ARROW )
wc.hbrBackground = win32con.COLOR_WINDOW
wc.lpfnWndProc = message_map # could also specify a wndproc.
classAtom = win32gui.RegisterClass(wc)
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = win32gui.CreateWindow( classAtom, "Taskbar Demo", style, \
0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
0, 0, hinst, None)
win32gui.UpdateWindow(self.hwnd)
def setIcon(self, hicon, tooltip=None):
self.hicon = hicon
self.tooltip = tooltip
def show(self):
"""Display the taskbar icon"""
flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE
if self.tooltip is not None:
flags = win32gui.NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, self.hicon, self.tooltip)
else:
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, self.hicon)
if self.visible:
self.hide()
win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid)
self.visible = 1
def hide(self):
"""Hide the taskbar icon"""
if self.visible:
nid = (self.hwnd, 0)
win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)
self.visible = 0
def onDestroy(self, hwnd, msg, wparam, lparam):
self.hide()
win32gui.PostQuitMessage(0) # Terminate the app.
hwnd, msg, wparam, lparam = 0,0,0,0
def onTaskbarNotify(self, hwnd, msg, wparam, lparam):
self.hwnd = hwnd
self.msg = msg
self.wparam = wparam
self.lparam = lparam
return 1
def start_tray(self):
icon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
self.setIcon(icon)
self.show()
Windows服务在与用户会话不同的会话(0)中运行,无法与用户的显示器交互。服务上有一个允许与桌面交互的标志,但由于潜在的安全问题,不建议这样做。正确的方法是在用户会话中设置一个进程,该进程与服务具有某种IPC机制,可以显示任何图形元素和用户交互。Windows服务在与用户会话不同的会话(0)中运行,并且不能与用户的显示交互。服务上有一个允许与桌面交互的标志,但由于潜在的安全问题,不建议这样做。正确的方法是在用户会话中创建一个进程,该进程与服务具有某种IPC机制,可以显示任何图形元素和用户交互。