'Automatically find the path of the python executable

I'm doing a project that uses python as background script and C# as guy. My problem is that I can't figure out how to cause my GUI to automatically search for the pythonw.exe file in order to run my python scripts.

Currently I'm using this path:

ProcessStartInfo pythonInfo = new ProcessStartInfo(@"C:\\Users\\Omri\\AppData\\Local\\Programs\\Python\\Python35-32\\pythonw.exe");

but I want it to auto detect the path of pythonw.exe (I need to submit the project and it won't run on others computers unless they change the code itself)

Any suggestions may be helpful.



Solution 1:[1]

You can find python installation path by lookup following keys on windows machine.

HKLM\SOFTWARE\Python\PythonCore\versionnumber\InstallPath

HKCU\SOFTWARE\Python\PythonCore\versionnumber\InstallPath

for win64 bit machine

HKLM\SOFTWARE\Wow6432Node\Python\PythonCore\versionnumber\InstallPath

You can refer this post for how to read registry using C#

How to read value of a registry key c#

Solution 2:[2]

Inspired by @Shashi Bhushan's answer I made this function for getting the Python path reliably;

        private static string GetPythonPath(string requiredVersion = "", string maxVersion = "") {
            string[] possiblePythonLocations = new string[3] {
                @"HKLM\SOFTWARE\Python\PythonCore\",
                @"HKCU\SOFTWARE\Python\PythonCore\",
                @"HKLM\SOFTWARE\Wow6432Node\Python\PythonCore\"
            };

            //Version number, install path
            Dictionary<string, string> pythonLocations = new Dictionary<string, string>();

            foreach (string possibleLocation in possiblePythonLocations) {
                string regKey = possibleLocation.Substring(0, 4), actualPath = possibleLocation.Substring(5);
                RegistryKey theKey = (regKey == "HKLM" ? Registry.LocalMachine : Registry.CurrentUser);
                RegistryKey theValue = theKey.OpenSubKey(actualPath);

                foreach (var v in theValue.GetSubKeyNames()) {
                    RegistryKey productKey = theValue.OpenSubKey(v);
                    if (productKey != null) {
                        try {
                            string pythonExePath = productKey.OpenSubKey("InstallPath").GetValue("ExecutablePath").ToString();
                            
                            // Comment this in to get (Default) value instead
                            // string pythonExePath = productKey.OpenSubKey("InstallPath").GetValue("").ToString();
                            
                            if (pythonExePath != null && pythonExePath != "") {
                                //Console.WriteLine("Got python version; " + v + " at path; " + pythonExePath);
                                pythonLocations.Add(v.ToString(), pythonExePath);
                            }
                        } catch {
                            //Install path doesn't exist
                        }
                    }
                }
            }

            if (pythonLocations.Count > 0) {
                System.Version desiredVersion = new System.Version(requiredVersion == "" ? "0.0.1" : requiredVersion),
                    maxPVersion = new System.Version(maxVersion == "" ? "999.999.999" : maxVersion);

                string highestVersion = "", highestVersionPath = "";

                foreach (KeyValuePair<string, string> pVersion in pythonLocations) {
                    //TODO; if on 64-bit machine, prefer the 64 bit version over 32 and vice versa
                    int index = pVersion.Key.IndexOf("-"); //For x-32 and x-64 in version numbers
                    string formattedVersion = index > 0 ? pVersion.Key.Substring(0, index) : pVersion.Key;

                    System.Version thisVersion = new System.Version(formattedVersion);
                    int comparison = desiredVersion.CompareTo(thisVersion),
                        maxComparison = maxPVersion.CompareTo(thisVersion);

                    if (comparison <= 0) {
                        //Version is greater or equal
                        if (maxComparison >= 0) {
                            desiredVersion = thisVersion;

                            highestVersion = pVersion.Key;
                            highestVersionPath = pVersion.Value;
                        } else {
                            //Console.WriteLine("Version is too high; " + maxComparison.ToString());
                        }
                    } else {
                        //Console.WriteLine("Version (" + pVersion.Key + ") is not within the spectrum.");
                    }
                }

                //Console.WriteLine(highestVersion);
                //Console.WriteLine(highestVersionPath);
                return highestVersionPath;
            }

            return "";
        }

Solution 3:[3]

Find the environment variable name in Windows, for that assembly and use Environment.GetEnvironmentVariable(variableName)

Check out How to add to the pythonpath in windows 7?

Solution 4:[4]

An example on how to search for Python within the PATH environment variable:

var entries = Environment.GetEnvironmentVariable("path").Split(';');
string python_location = null;

foreach (string entry in entries)
{
    if (entry.ToLower().Contains("python"))
    {
        var breadcrumbs = entry.Split('\\');
        foreach (string breadcrumb in breadcrumbs)
        {
            if (breadcrumb.ToLower().Contains("python"))
            {
                python_location += breadcrumb + '\\';
                break;
            }
            python_location += breadcrumb + '\\';
        }
        break;
    }
}

Solution 5:[5]

Just change the FileName to "python.exe" if you already set python env path

private void runPython(string cmd, string args)
    {
        ProcessStartInfo start = new ProcessStartInfo();
        start.FileName = "python.exe";
        start.Arguments = string.Format("{0} {1}", cmd, args);
        start.UseShellExecute = false;
        start.RedirectStandardOutput = true;
        using (Process process = Process.Start(start))
        {
            using (StreamReader reader = process.StandardOutput)
            {
                string result = reader.ReadToEnd();
                Console.Write(result);
            }
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 albusSimba
Solution 3 Community
Solution 4 Ernest Krom
Solution 5 Allen Yu