UPDATE Dec 2022
There are 2 optional environment strings you can use to locate the python dll.
PYTHONNET_PYDLL explicitly set the dll name
PYTHONNET_PYVER explicitly set just the version string part of the dll name
Compiling with WINDOWS, OSX or LINUX defined is not required anymore
Here's my PythonNet init function.
Note that running "pip install pythonnet" only installs the ability to load & use CLR types & assemblies from Python. To embed PythonNet in a C# app, you actually don't need to install pythonnet on the Python side.
This function uses some globals set at startup.
- Program.PythonHome -- points to the Python root folder I'm using
- Program.ScriptsDir -- my own app python scripts dir
- Program.ApplicationName -- just my own app name
I also call PythonEngine.BeginAllowThreads(); as I'm calling from multiple threads.
public static void InitPython(Microsoft.Extensions.Logging.ILogger logger)
{
string py_home = Program.PythonHome;
string py_path = $"{py_home};";
// will be different on linux/mac
string[] py_paths = {"DLLs", "lib", "lib/site-packages", "lib/site-packages/win32"
, "lib/site-packages/win32/lib", "lib/site-packages/Pythonwin" };
foreach (string p in py_paths)
{
py_path += $"{py_home}/{p};";
}
try
{
PythonEngine.PythonPath = $"{Program.ScriptsDir};{py_path}";
PythonEngine.PythonHome = Program.PythonHome;
PythonEngine.ProgramName = Program.ApplicationName;
PythonEngine.Initialize();
PythonEngine.BeginAllowThreads();
logger.LogInformation("Python Version: {v}, {dll}", PythonEngine.Version.Trim(), Runtime.PythonDLL);
logger.LogInformation("Python Home: {home}", PythonEngine.PythonHome);
logger.LogInformation("Python Path: {path}", PythonEngine.PythonPath);
}
catch (System.TypeInitializationException e)
{
throw new Exception($"FATAL, Unable to load Python, dll={Runtime.PythonDLL}", e);
}
catch (Exception e)
{
throw new Exception($"Python initialization Exception, {e.Message}", e);
}
}