Fatal Python error: failed to get random numbers to initialize Python
Environment windows 10, VSC 15
Using CreateProcessA winapi and passing lpenvironment variable to run python with scripts. when lpenvironment is passed null, it works fine. If I set environment variable PATH and PYTHONPATH = "paths", and pass that LPSTR(env.c_Str()), it throws above error on running. The python version is 3.5.6
Any help?
Some more details.
For some reason, the 7th parameter in CreateProcessA fails, the python.exe runs successfully if it is null, or else it prints "Fatal Python error: failed to get random numbers to initialize Python".
std::string Base = Configuration::getBasePath();
std::string environPython = Base;
environPython.append("\\Python;");
environPython.append(Base);
environPython.append("\\Python\\Scripts;");
environPython.append(Base);
environPython.append("\\Python\\include;");
environPython.append(Base);
environPython.append("\\Python\\Lib;");
environPython.append(Base);
environPython.append("\\Python\\libs;");
environPython.append(Base);
environPython.append("\\Python\\Lib\\site-packages;");
environPython.append(Base);
environPython.append("\\Python\\_ML;");
environPython.push_back('\0');
std::string environPath = Base;
environPath.append("\\Python;");
environPath.append(Base);
environPath.append("\\Python\\Lib;");
environPath.append(Base);
environPath.append("\\Python\\Scripts;");
environPath.append(Base);
environPath.append("\\Python\\libs;");
environPath.push_back('\0');
std::string cmd = Base;
cmd.append("\\Python\\python.exe");
std::string params = "\"";
params.append(cmd);
params.append("\" \"");
params.append(Base);
params.append("\\Python\\_ML\\mlprocessor_server.py\"");
std::map env = { { "PYTHONPATH", environPython.data() }, { "PATH", environPath.data() }};
// example for generating block of strings
std::vector<char> envBlock;
std::for_each(env.begin(), env.end(),
[&envBlock](const std::pair<std::string, std::string> & p) {
std::copy(p.first.begin(), p.first.end(), std::back_inserter(envBlock));
envBlock.push_back('=');
std::copy(p.second.begin(), p.second.end(), std::back_inserter(envBlock));
envBlock.push_back('\0');
}
);
envBlock.push_back('\0');
// feed this into ::CreateProcess()
LPVOID lpEnvironment = (LPVOID)envBlock.data();
bool result = CreateProcessA(cmd.c_str(), (LPSTR)params.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, lpEnvironment, NULL, &info, &pi);
The result is always true, python.exe is not shown up in task manager and gives Fatal Python error: failed to get random numbers to initialize Python.
If the lpEnvironment is NULL, python.exe is shown up in task manager.
The environment you pass to CreateProcessA
must include SYSTEMROOT
, otherwise the Win32 API call CryptAcquireContext
will fail when called inside python during initialization.
When passing in NULL as lpEnvironment, your new process inherits the environment of the calling process, which has SYSTEMROOT
already defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With