在 Windows 中将程序作为服务运行时如何初始化 python?

问题描述 投票:0回答:1

我正在创建一个基于SFL(服务框架库)的服务。当我从控制台工作时,没问题,但是当我通过“sc start MyService”将其作为服务运行时,在调用 Py_Initialize 等时会发出致命错误。

当程序崩溃时,将以下行发送到调试器:

致命的Python错误:无法获取文件系统编码的Python编解码器

sc 查询 MyService 输出:

SERVICE_NAME: MyService 
TYPE : 10
WIN32_OWN_PROCESS STATE : 1
STOPPED WIN32_EXIT_CODE : 1077 (0x435)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
#include "SflBase.h"
namespace nsSFL                                                                             
{                                                                                           
    const CMyService* SflGetServiceApp(void)                                                         
    {                                                                                       
        static T theApp;                                                                    
        return &theApp;                                                                     
    }                                                                                       
}                                                                                           
int _tmain( int argc, LPTSTR* argv )                                                        
{            
    CMyService* pApp = const_cast<CMyService*>( SFL_NS SflGetServiceApp() );                                  
    nsSFL::CServiceRoot* pServiceMap[] = {                                                  
       nsSFL::CServiceProxyT<CMyService, 0>::Construct2((TService*)NULL, L"CMyService")                                                                          
    };                                                                                      
    int retMain = -1;
    if(pApp->PreMain(argc, argv))
        retMain = pApp->Main( argc, argv, pServiceMap, ARRAYSIZE(pServiceMap));
    pApp->PostMain();
    return retMain;
}
BOOL CMyService::PreMain(int argc, LPTSTR* argv)
{   
    if (!InitInstance(argc, argv))
    {
        return FALSE;
    }
    return TRUE;
}
BOOL CMyService::InitInstance(DWORD argc, LPTSTR* lpszArgv)
{
    if (!AfxWinInit(::GetModuleHandle(nullptr), nullptr, ::GetCommandLine(), 0))
    {
        return FALSE;
    }
    {
        PyPreConfig preconfig;
        PyPreConfig_InitIsolatedConfig(&preconfig);
        preconfig.utf8_mode = true;

        status = Py_PreInitialize(&preconfig);
        pystatus_exit_on_error(status);
    }

    // auto pythonPath = L"%localappdata%\\Programs\\Python\\Python38\\python.exe";
    auto pythonPath = L"C:\\Program Files\\Python38\\python.exe";
    Py_SetPythonHome(pythonPath);
    Py_Initialize(); // print "Fatal Python error" only then work as service
}

项目属性:C++20、SDK Windows 10.0.20348.0、Visual Studio 2022 (v143)、python 3.8,均为 x64,boost 1.77

根据这个问题我尝试取消设置

PYTHONPATH
PYTHONHOME
,但系统中不可用,所以我设置了这些变量(仍然错误),并从环境变量中取消设置它们(仍然错误)。

根据那个问题我尝试分配Py_SetPythonHome,但不是“C:\ Program Files \ Python38 \ python.exe”的路径,也不是“%localappdata%\ Programs \ Python \ Python38 \ python.exe”没有以任何方式影响错误。 使用 PyConfig_InitIsolatedConfig/PyConfig_InitPythonConfig 也没有解决问题。

我认为问题与 LocalSystem 的一些限制有关,尽管 NetworkService 根本拒绝启动并且 LocalService 不适合,因为我需要使用端口。也许我应该设置某种访问权限,但我不知道如何甚至在哪里可以找到信息。

c++ python-3.x winapi windows-services boost-python
1个回答
0
投票

我决定尝试填写配置器的所有文本变量,结果这就是答案:

wchar_t pythonPath[MAX_PATH * 3];
wchar_t pythonExe[MAX_PATH];
wchar_t pythonHome[] = L"%localappdata%\\Programs\\Python\\Python38"; // L"C:\\Program Files\\Python38";

(void)swprintf_s(pythonPath, L"%s\\Lib;%s\\DLLs;%s\\Lib\\site-packages", pythonHome, pythonHome, pythonHome);
PathCombineW(pythonExe, pythonHome, L"python.exe");

PyConfig config;
PyConfig_InitPythonConfig(&config);
PyConfig_SetString(&config, &config.executable, pythonExe);
PyConfig_SetString(&config, &config.home, pythonHome);
PyConfig_SetString(&config, &config.pythonpath_env, pythonPath);

PyStatus status = Py_InitializeFromConfig(&config);
if (PyStatus_Exception(status) || !Py_IsInitialized()) 
{
    CMyService::LogPythonError(L"Python initialization failed");
    CMyService::LogTextEvent(pythonPath);
    PyConfig_Clear(&config);
    return false;
}

PyConfig_Clear(&config);
© www.soinside.com 2019 - 2024. All rights reserved.