首页 > 技术文章 > python开发win_service问题记录

ham-731 2021-03-03 10:07 原文

1. 调试工具介绍

a:自带debug模式

 .\service.exe debug
Traceback (most recent call last):
  File "service.py", line 50, in <module>
  File "win32serviceutil.py", line 548, in HandleCommandLine
  File "win32serviceutil.py", line 484, in GetServiceClassString
ModuleNotFoundError: No module named 'win32timezone'
[10308] Failed to execute script service

b: windows事件查看器

2 三种运行方式差异问题处理

a py文件运行

"例: python service.py install"
"例: python service.py start"

b pyinstaller(打包后运行)

"例: service.exe install"
  • 问题1: __file__ 位置改变为("C:\Windows\System32")

c pyinstaller(打包成单文件后运行)

"例: service.exe install"
  • 问题1: __file__ 位置改变为("C:\Windows\System32")
  • 问题2: Popen执行终端命令报错

三种情况运行服务对程序的运行有很大的影响

同时debug和start方式运行也存在运行位置差异问题

3 自带命令

win_service\dist> .\service.exe
Usage: 'service.exe [options] install|update|remove|start [...]|stop|restart [...]|debug [...]'
Options for 'install' and 'update' commands only:
 --username domain\username : The Username the service is to run under
 --password password : The password for the username
 --startup [manual|auto|disabled|delayed] : How the service starts, default = manual
 --interactive : Allow the service to interact with the desktop.
 --perfmonini file: .ini file to use for registering performance monitor data
 --perfmondll file: .dll file to use when querying the service for
   performance data, default = perfmondata.dll
Options for 'start' and 'stop' commands only:
 --wait seconds: Wait for the service to actually start or stop.
                 If you specify --wait with the 'stop' option, the service
                 and all dependent services will be stopped, each waiting
                 the specified period.
                 
1.安装服务
service.exe install
 
2.让服务自动启动
service.exe --startup auto install 
 
3.启动服务
service.exe start
 
4.重启服务
service.exe restart
 
5.停止服务
service.exe stop
 
6.删除/卸载服务
service.exe remove

4 常见问题

  • ModuleNotFoundError: No module named 'win32timezone'

    import win32timezone  # 导入win32timezone
    
  • __file__ 目录偏移

    # 1 sys模块获取执行文件目录
    # 适用于非单文件打包
    sys.path[1]
    
    # 单文件打包后 获取的目录都是C:\Windows\system32
    # 需要使用其他方法 如固定安装位置
    
    # 打包单文件获取运行目录
    2021-03-03 09:48:31,279 [PythonService] INFO     sys.path: ['C:\\Windows\\TEMP\\_MEI69562\\base_library.zip', 'C:\\Windows\\TEMP\\_MEI69562']
    2021-03-03 09:48:31,279 [PythonService] INFO     inspect.getfile: C:\Windows\system32
    
    # 打包非单文件获取运行目录
    2021-03-03 09:50:03,074 [PythonService] INFO     sys.path: ['F:\\Aqjun\\MyCode\\sccin\\qpkg\\win_service\\dist\\service\\base_library.zip', 'F:\\Aqjun\\MyCode\\sccin\\qpkg\\win_service\\dist\\service']
    2021-03-03 09:50:03,074 [PythonService] INFO     inspect.getfile: C:\Windows\system32
    
    # py文件方式运行
    (base) F:\Aqjun\MyCode\sccin\qpkg\win_service>python service.py install
    Installing service PythonService
    Changing service configuration
    Service updated
    (base) F:\Aqjun\MyCode\sccin\qpkg\win_service>python service.py start
    Starting service PythonService
    (base) F:\Aqjun\MyCode\sccin\qpkg\win_service>python service.py stop
    Stopping service PythonService
    2021-03-03 09:51:28,871 [PythonService] INFO     sys.path: ['F:\\Aqjun\\MyCode\\sccin\\qpkg\\win_service', 'C:\\Abin\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Abin\\Anaconda3\\python37.zip', 'C:\\Abin\\Anaconda3\\DLLs', 'C:\\Abin\\Anaconda3\\lib', 'C:\\Abin\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Abin\\Anaconda3', 'C:\\Abin\\Anaconda3\\lib\\site-packages', 'C:\\Abin\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Abin\\Anaconda3\\lib\\site-packages\\Pythonwin']
    2021-03-03 09:51:28,871 [PythonService] INFO     inspect.getfile: F:\Aqjun\MyCode\sccin\qpkg\win_service
    
  • Error starting service: 服务没有及时响应启动或控制请求。

    # 使用下面的方式启动
    if __name__ == '__main__':
        import servicemanager
        if len(sys.argv) == 1:
            try:
                evtsrc_dll = os.path.abspath(servicemanager.__file__)
                # 如果修改过名字,名字要统一
                servicemanager.PrepareToHostSingle(PythonService)
                # 如果修改过名字,名字要统一
                servicemanager.Initialize('PythonService', evtsrc_dll)
                servicemanager.StartServiceCtrlDispatcher()
            except win32service.error as details:
                import winerror
                if details == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
                    win32serviceutil.usage()
        else:
            # 如果修改过名字,名字要统一
            win32serviceutil.HandleCommandLine(PythonService)
    
  • 调用Popen错误 WinError 6

      File "subprocess.py", line 753, in __init__
      File "subprocess.py", line 1054, in _get_handles
    OSError: [WinError 6] 鍙ユ焺鏃犳晥銆? 
    
    没有什么好建议 只能不打包成单文件exe 用python脚本或打包成目录
    

开发建议

  • 最好在目标主机上安装python 使用.py文件作为服务 这样问题少
  • pyinstaller 别加 -F

模版参考: https://blog.csdn.net/kmust20093211/article/details/42169323

推荐阅读