Pythonnet: Running Embedded Python.NET Application on Environment without Python Installed?

Created on 17 May 2017  路  9Comments  路  Source: pythonnet/pythonnet

Environment

  • Pythonnet version: 2.2.2
  • Python version: 2.7
  • Operating System: Windows 10

Details

I haven't worked _too_ extensively with Python previously, but I've been experimenting with the idea of writing some utilities using it and embedding them within a .NET application (e.g. Windows Forms, Console, WPF, etc.). Is it possible to embed Python itself within the assembly using Python.NET or is it required that Python be installed on the executing machine?

Any attempts that I made to run outside of my development environment (with Python 2.7 installed), resulted in an error about a missing python27.dll, which I couldn't seem to figure out how to include, and I may just be missing something.

Ideally, I'd like to be able to package this up as an executable, distribute it to users, who will likely not have Python installed on their machine. I know that the documentation mentions the need for an interpreter and I was wondering if the one available with IronPython would suffice?

Any advice would be appreciated. I understand that this _may_ not be plausible, but I'd love to take advantage of using Python.NET for this if possible.

Most helpful comment

@wdrobinson HI I'm new so bare with me,My code looks like this
private string path = Environment.CurrentDirectory+"\\packages\\Python35\\";
PythonEngine.PythonHome=path;
PythonEngine.Initialize();

But your's is
var path = $"{Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine)};
{pythonPath}";
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);

I need explanation of how you're setting path without using
PythonEngine.PythonHome=path;
and what is %path%

All 9 comments

That is exactly what I'm doing with pythonnet, but I install CPython as part of larger installation.

@rionmonster one option would be to use the nuget packages for CPython and pythonnet:

https://www.nuget.org/packages/python2/
https://www.nuget.org/packages/pythonnet_py27_dotnet/

When embedding this nuget package in .NET app, you will need to set PYTHONHOME environment variable or this property PythonEngine.PythonHome in pythonnet so that CPython can be located at runtime.

Thanks for the insights @denfromufa

I eventually elected to go another route for the time being, but I was able to play around with the use of PythonHome along with the aforementioned NuGet packages. That's certainly an option I'll consider should the need arise again.

I appreciate it.

@denfromufa @rionmonster I'm attempting to do the same thing. I installed pythonnet_py27_dotnet & python2 via nuget and then I'm setting PythonEngine.PythonHome to the location of the python2 folder. Python.Runtime is giving me an error: "Unable to load DLL 'python27': The specified module could not be found." even though the DLL is in the PythonHome folder.

If I drop the DLL in the appropriate Windows\System location everything works as expected but that's what I'm trying to avoid. Any ideas on how to get pythonnet to find the python27 DLL?

@willdrob you may need to append this python path to %path% env. var. too.

Also there is outstanding issue with explicitly picking the 64-bit binary if you have Python 64-bit:

https://github.com/pythonnet/pythonnet/issues/472#issuecomment-304121261

@denfromufa you are correct, I needed to append the python path to %path%.
var path = $"{Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine)};{pythonPath}";
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);
It's working now, thanks for the help!

@rionmonster @denfromufa I am also implementing a similar process for packaging python code to be used within a Windows application without requiring the user to install Python. I found a way to include the python runtime as well as dependent libraries in the project itself. It turns out if you include the PythonRuntime.dll in the project and include the dependent libraries in a Lib folder in the same directory, the python script is able to be loaded and used correctly.

I am running into an issue though being that if the PYTHONHOME environment variables are set (for some system python installation), then the pythonruntime.dll will no longer find the python files in the project. It seems to prioritize searching in the paths set by environment variables first. Then if environment variables are set, the pythonruntime.dll will no longer look in the project directory.

The problem is I want to prefer using the python dependencies in my project as opposed to the user's system install since the user may not have the necessary dependencies and versions installed.

Do you all know of a fix for this? Is it possible to change the search prioritization in the Pythonnet runtime DLL?

@ryan-rogowski just hide %PYTHONHOME% in your app before loading Python runtime.

@ryan-rogowski just hide %PYTHONHOME% in your app before loading Python runtime.

Thanks @denfromufa ! Do you mean to set PYTHONHOME to an empty string prior to loading Python runtime? or how would I go about hiding the environment variable from my app?

        //Check if python environment variable is set
        string path = Environment.GetEnvironmentVariable("PYTHONHOME", EnvironmentVariableTarget.Machine);
        if (path != null) {
            Environment.SetEnvironmentVariable("PYTHONHOME", "");
        }

@wdrobinson HI I'm new so bare with me,My code looks like this
private string path = Environment.CurrentDirectory+"\\packages\\Python35\\";
PythonEngine.PythonHome=path;
PythonEngine.Initialize();

But your's is
var path = $"{Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine)};
{pythonPath}";
Environment.SetEnvironmentVariable("Path", path, EnvironmentVariableTarget.Process);

I need explanation of how you're setting path without using
PythonEngine.PythonHome=path;
and what is %path%

Was this page helpful?
0 / 5 - 0 ratings