1

I am creating a service based on SFL (Service Framework Library). When I work from the console, it is okay, but when I run it as a service, via "sc start MyService", it issues fatal errors when calling Py_Initialize and the like.

When the program crashes, the following line is sent to the debugger:

Fatal Python error: failed to get the Python codec of the filesystem encoding

sc query MyService outputs this:

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
}

Project Properties: C++20, SDK Windows 10.0.20348.0, Visual Studio 2022 (v143), python 3.8, all is x64, boost 1.77

According to this question I tried to unset PYTHONPATH and PYTHONHOME, but it was not available in the system, so I set these variables (error remained), and unset them from the environment variables (error remained).

According to that question I tried to assign Py_SetPythonHome, but not the path to "C:\Program Files\Python38\python.exe ", nor "%localappdata%\Programs\Python\Python38\python.exe" did not affect the error in any way. Using PyConfig_InitIsolatedConfig/PyConfig_InitPythonConfig also did not solve the problem.

I think the problem is related to some limitations of LocalSystem, although NetworkService refuses to start at all and LocalService is not suitable since I need to work with ports. Maybe I should set up some kind of access rights but I have no idea how or even where to find information.

1

1 Answer 1

0

I decided to try to fill in all the text variables of the configurator and this turned out to be the answer:

wchar_t pythonPath[MAX_PATH * 3];
wchar_t pythonExe[MAX_PATH];
wchar_t pythonHome[] = 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);
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.