致命的Python错误:无法获取随机数以初始化Python
环境窗口10,VSC 15
使用CreateProcessA winapi并传递lpenvironment变量来运行带有脚本的python。当lpenvironment被传递为null时,它工作正常。如果我设置环境变量PATH和PYTHONPATH =“paths”,并传递该LPSTR(env.c_Str()),它在运行时抛出上述错误。python版本是3.5.6
有什么帮助吗?
更多细节。
1.我使用CreateProcessA WINAPI运行子进程python.exe“C:\Program Files\endpoint\Python_ML\mlprocessor_server.py”。
1.我想用两个环境变量“PYTHONPATH”和“PATH”运行子进程。PYTHONPATH=“C:\Program Files\endpoint\Python”;C:\Program Files\endpoint\Python\ScriptsC:\Program Files\endpoint\Python\include“C:\Program Files\endpoint\Python\Lib”;“C:\Program Files\endpoint\Python\libs”;“C:\Program Files\endpoint\Python\Lib\site-packages”;“C:\Program Files\endpoint\Python_ML”PATH=“C:\Program Files\endpoint\Python”;“C:\Program Files\endpoint\Python\Lib”;C:\Program Files\endpoint\Python\Scripts“C:\Program Files\endpoint\Python\libs”
由于某种原因,CreateProcessA中的第7个参数失败,如果它为null,则python.exe成功运行,否则它会打印“Fatal Python error:无法获取随机数以初始化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);
结果总是true,python.exe没有显示在任务管理器中,并给出致命的Python错误:无法获取随机数以初始化Python。
如果lpEnvironment为NULL,则python.exe将显示在任务管理器中。
2条答案
按热度按时间rekjcdws1#
传递给
CreateProcessA
的环境必须包含SYSTEMROOT
,否则在初始化期间在python内部调用时,Win32 API调用CryptAcquireContext
将失败。当传入NULL作为lpEnvironment时,新进程将继承调用进程的环境,该环境已经定义了
SYSTEMROOT
。mum43rcc2#
下面我们举一个例子,在真实的世界中的纯Python软件中,这是如何很容易被触发的,有时Python打开一个自己的示例来执行一些任务是很有用的,其中子任务需要设置一个特定的
PYTHONPATH
。通常情况下,这可能是在不太复杂的平台上(即不是Windows)懒洋洋地完成的,如下所示:然而,在Windows上这样做,将导致以下令人困惑的失败:
解决办法很明显:克隆
os.environ
以确保SYSTEMROOT
到位,从而避免@Joe Savage的答案所指出的问题,例如:需要此类修复的真实的世界示例:
setuptools
(仅在测试中,但作为一个例子,显示了这个错误是多么容易被几乎任何人)。