Python Win32服务除了在调试模式下启动

发布于 2025-02-02 07:01:36 字数 3626 浏览 2 评论 0原文

我有一个Django应用程序,我正在尝试通过Windows Server上的Cherrypy运行。我在服务创建脚本中的代码以下。

import os
import sys

service_directory = os.path.dirname(__file__)
source_directory = os.path.abspath(service_directory)
os.chdir(source_directory)
venv_base = os.path.abspath(os.path.join(source_directory, ".venv"))
print(venv_base)
sys.path.append(".")
old_os_path = os.environ['PATH']
os.environ['PATH'] = os.path.join(venv_base, "Scripts")+ os.pathsep + old_os_path
site_packages = os.path.join(venv_base, "Lib", "site-packages")
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = venv_base
new_sys_path = list()
for item in list(sys.path):
    if item not in prev_sys_path:
        new_sys_path.append(item)
        sys.path.remove(item)
sys.path[:0] = new_sys_path

import pathlib
import subprocess
import traceback
import servicemanager
import win32event
import win32service
import win32serviceutil
from win32api import SetConsoleCtrlHandler

class AppServerSvc(win32serviceutil.ServiceFramework):
    """
    Service Create class
    """
    _svc_name_ = "MyService"  # service name
    _svc_display_name_ = "MyService"  # display name

    def __init__(self, args):
        """
        Constructor
        """
        win32serviceutil.ServiceFramework.__init__(self, args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        """
        Function to stop the windows service
        """
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.proc.terminate()

    def SvcDoRun(self):
        """
        Function to create and start the windows service
        """
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ''))
        try:
            self.main()

        except Exception as exp_msg:
            servicemanager.LogErrorMsg(traceback.format_exc())
            os._exit(-1)

    def main(self):
        """
        Script to run as the windows service
        """
        #env_file.load(f'{os.path.join(pathlib.Path(__file__).parent.absolute(), "config.env")}')
        #settings.set_env_variables()
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        self.proc = subprocess.Popen(f"python"
                                     f" {os.path.join(pathlib.Path(__file__).parent.absolute(), 'cherryd.py')} 1"
                                     , stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                     stdin=subprocess.DEVNULL)
        stdout, stderr = self.proc.communicate()
        print(stdout)
        if (self.proc.poll() == 0):
            servicemanager.LogMsg(f"Successfully started the process with PID: {self.proc.pid}")
        else:
            servicemanager.LogErrorMsg(f"Failed to start the services")


if __name__ == '__main__':
    # Start of the process
    win32serviceutil.HandleCommandLine(AppServerSvc)

我可以使用python service.py install安装此服务,这里没有问题。 当我启动服务python service.py start我获得错误错误启动服务:服务没有及时响应开始或控制请求。

当我执行python service.py debug,一切正常,我能够使用FQDN访问该应用程序。为什么服务在正常启动时不起作用,并且仅在调试模式下工作。

已经阅读了有关类似错误的多个帖子,但没有任何帮助。我正在使用Python 3.8,并将VENV脚本目录也添加到路径中。有人可以帮忙吗?

更新 使用我的用户帐户开始服务,并且它可以正常工作,但仍然不了解其在调试模式下的工作方式。

I have a Django app that I'm trying to run via Cherrypy on Windows Server. I have below code in the service creation script.

import os
import sys

service_directory = os.path.dirname(__file__)
source_directory = os.path.abspath(service_directory)
os.chdir(source_directory)
venv_base = os.path.abspath(os.path.join(source_directory, ".venv"))
print(venv_base)
sys.path.append(".")
old_os_path = os.environ['PATH']
os.environ['PATH'] = os.path.join(venv_base, "Scripts")+ os.pathsep + old_os_path
site_packages = os.path.join(venv_base, "Lib", "site-packages")
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = venv_base
new_sys_path = list()
for item in list(sys.path):
    if item not in prev_sys_path:
        new_sys_path.append(item)
        sys.path.remove(item)
sys.path[:0] = new_sys_path

import pathlib
import subprocess
import traceback
import servicemanager
import win32event
import win32service
import win32serviceutil
from win32api import SetConsoleCtrlHandler

class AppServerSvc(win32serviceutil.ServiceFramework):
    """
    Service Create class
    """
    _svc_name_ = "MyService"  # service name
    _svc_display_name_ = "MyService"  # display name

    def __init__(self, args):
        """
        Constructor
        """
        win32serviceutil.ServiceFramework.__init__(self, args)
        SetConsoleCtrlHandler(lambda x: True, True)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        """
        Function to stop the windows service
        """
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.proc.terminate()

    def SvcDoRun(self):
        """
        Function to create and start the windows service
        """
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ''))
        try:
            self.main()

        except Exception as exp_msg:
            servicemanager.LogErrorMsg(traceback.format_exc())
            os._exit(-1)

    def main(self):
        """
        Script to run as the windows service
        """
        #env_file.load(f'{os.path.join(pathlib.Path(__file__).parent.absolute(), "config.env")}')
        #settings.set_env_variables()
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        self.proc = subprocess.Popen(f"python"
                                     f" {os.path.join(pathlib.Path(__file__).parent.absolute(), 'cherryd.py')} 1"
                                     , stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                     stdin=subprocess.DEVNULL)
        stdout, stderr = self.proc.communicate()
        print(stdout)
        if (self.proc.poll() == 0):
            servicemanager.LogMsg(f"Successfully started the process with PID: {self.proc.pid}")
        else:
            servicemanager.LogErrorMsg(f"Failed to start the services")


if __name__ == '__main__':
    # Start of the process
    win32serviceutil.HandleCommandLine(AppServerSvc)

I'm able to install this service using python service.py install, no issues here.
When I start the service python service.py start I get error Error starting service: The service did not respond to the start or control request in a timely fashion.

When I do python service.py debug, everything works normal and I'm able to access the app using FQDN. Why does the service not work when started normally and work only during debug mode.

Have read multiple posts on similar errors but nothing helped. I'm using Python 3.8 and have added the venv Scripts directory to PATH as well. Can someone please help.

Update
Started the service with my user account and it worked, still don't understand how it worked in debug mode.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文