无法启动用Python编写的Windows服务(win32serviceutil)

19

我正在尝试启动一个简单的服务示例:

someservice.py:

import win32serviceutil 
import win32service 
import win32event

class SmallestPythonService(win32serviceutil.ServiceFramework):
    _svc_name_ = "SmallestPythonService"
    _svc_display_name_ = "display service"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

if __name__=='__main__':
    win32serviceutil.HandleCommandLine(SmallestPythonService)

当我运行时

python someservice.py install

所有的一切都很好,服务也出现在Windows服务列表中,但是

python someservice.py start

出现"错误 1053: 服务未能在适当的时间内响应启动或控制请求",但没有任何延迟。

我搜索了解决方案,发现是因为pythonservice.exe找不到python27.dll导致的。我将C:\Python27添加到PATH中,问题得到了解决。现在pythonservice.exe可以正常运行,但错误1053仍然存在。

我在Windows 7 Ultimate上以管理员权限运行Python 2.7.2和pywin32 216。


这对我有用,运行Python 2.6.6(64位)和pywin32 216 amd64-py26。我意识到这并不是很有帮助。在Windows 7 Pro上。 - jgritty
3
如果 pythonservice.exe 找不到 python27.dll,就会出现错误 1053。我花了很长时间才明白这一点!谢谢 :) - Gili
8个回答

16

另外,感谢你指出这可能是DLL问题,这让我找到了正确的解决方案。

你需要做的是将Python27添加到系统路径,而不是用户路径,因为默认情况下Python服务将被安装为'LocalSystem',因此当它尝试启动时,它使用系统路径变量 -这就是为什么你可以从命令提示符运行它,你的用户路径是正确的。

希望这有所帮助!


9
在这种情况下,将这些目录添加到系统路径可能会有所帮助:C:\Python27\Lib\site-packages\win32C:\Python27\Lib\site-packages\pywin32_system32。这样您就可以更轻松地使用pythonservice了。 - BuvinJ
@BuvinJ 这解决了我在使用PythonService.exe时遇到的1053错误。谢谢! - Kenneth
@mpaf 能帮忙描述如何将东西添加到系统路径吗?啊,我明白了,你只需在“系统控制面板”中将其添加到整个计算机系统路径中即可。就我个人而言,我必须像 https://www.snip2code.com/Snippet/770602/setup-python-script-as-windows-service 中添加anaconda。 - Thomas Ahle

6
我也遇到了这个问题,并通过在我的"__main__"执行块中添加以下代码解决了它:
if len(sys.argv) == 1:
    servicemanager.Initialize()
    servicemanager.PrepareToHostSingle(RouterService)
    servicemanager.StartServiceCtrlDispatcher()
else:
    win32serviceutil.HandleCommandLine(RouterService)

请在文件顶部导入servicemanager。(Don't forget to import servicemanager at the top of the file)。
我认为问题在于Windows服务管理器默认情况下不带任何参数运行可执行文件,因此需要适当地告知应用程序启动服务,似乎不会自动调用"SvcDoRun"。
正如其他人所提到的,如果您从命令行运行此操作,则确实需要路径映射。在我的应用程序中,我使用了"cx_freeze"来冻结服务,并使用可执行文件安装服务,以便包含所有依赖项。

4
我相信通过更改方法SvcDoRun,您的问题将得到解决。

更改前:

   def  SvcDoRun(self):
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

to

   def  SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

2
请确保您使用与默认Local System用户不同的用户运行应用程序。将其替换为您成功运行调试命令的用户。
要更改用户,请转到Windows服务(开始>服务.msc) 右键单击创建的服务>属性>登录 取消选中本地系统帐户并输入您自己的帐户。 来自所有Python Windows服务无法启动{错误1053}对我有用。
因为我只为用户设置了PATH,在Local System Account下运行时缺少环境。

1
这个解决方案对我在Python 3.8上有效,我尝试了其他解决方案,例如将win32添加到系统路径,还有将pywintypes38.dll添加到win32中,但是这些都没有起作用。 - user2171775

1

另一个有用的提示是在调用之前添加以下行:

sys.frozen = 'windows_exe' # 伪装py2exe以便我们可以进行调试

注意:请保留html标签。

win32serviceutil.HandleCommandLine(...)

那样你就可以从服务中获得更多有用的信息,了解出现了什么问题。

1
我也无法启动Python服务,我已经安装了Python39。
我的问题是缺少pywintypes39.dll,这导致错误1053无法启动服务。
在Windows中负责启动Python服务的模块可以在以下路径找到:C:\Users\.....\AppData\Local\Programs\Python\Python39\Lib\site-packages\win32 pythonservice.exe 但是缺少的.dll文件安装在名为lib的子文件夹中:\AppData\Local\Programs\Python\Python39\Lib\site-packages\win32\lib
将缺失的.dll文件从Lib文件夹转移到根文件夹win32中,其中pythonservice.exe将使服务程序可访问。
对我有用。

0

我能够按照这些步骤使用Python 3.5和PyInstaller来运行服务。


0

错误的原因可能有许多。除了使用日志流之外,我强烈建议考虑使用nssmhttp://nssm.cc/download

根据我的经验,我曾经为将Python文件、批处理文件(.bat)和可执行文件创建Windows服务而苦苦挣扎。与使用sc或win32serviceutil从原始Python代码中安装服务相比,Nssm是一个非常优秀的工具。

创建一个模块来调用主函数并在批处理文件内运行该模块即可。然后可以使用该批处理文件作为Windows服务。

在Python模块中:

""" 
main.py 
""" 
from myCode import run.py

run()

在service.bat文件中:
python main.py

然后使用nssm,您可以轻松地安装一个指向service.bat文件的Windows服务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接