How do I run a Python script from C#?
The reason it isn't working is because you have UseShellExecute = false
.
If you don't use the shell, you will have to supply the complete path to the python executable as FileName
, and build the Arguments
string to supply both your script and the file you want to read.
Also note, that you can't RedirectStandardOutput
unless UseShellExecute = false
.
I'm not quite sure how the argument string should be formatted for python, but you will need something like this:
private void run_cmd(string cmd, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "my/full/path/to/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);
}
}
}
calling python.py from C# .net
The following code snippet worked for me : C# code to call Python
using System;
using System.Diagnostics;
using System.IO;
namespace ScriptInterface
{
public class ScriptRunner
{
//args separated by spaces
public static string RunFromCmd(string rCodeFilePath, string args)
{
string file = rCodeFilePath;
string result = string.Empty;
try
{
var info = new ProcessStartInfo(@"C:\Users\xyz\AppData\Local\Programs\Python\Python37\python.exe");
info.Arguments = rCodeFilePath + " " + args;
info.RedirectStandardInput = false;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
using (var proc = new Process())
{
proc.StartInfo = info;
proc.Start();
proc.WaitForExit();
if (proc.ExitCode == 0)
{
result = proc.StandardOutput.ReadToEnd();
}
}
return result;
}
catch (Exception ex)
{
throw new Exception("R Script failed: " + result, ex);
}
}
public static void Main()
{
string args = "1 2";
string res = ScriptRunner.RunFromCmd(@"your file path", args);
}
}
}
and following Python Code which takes two inputs and returns the sum of those:
import sys
def add_numbers(x,y):
sum = x + y
return sum
num1 = int(sys.argv[1])
num2 = int(sys.argv[2])
print(add_numbers(num1, num2))
Executing Python Script from Windows Forms .NET
After some struggle, I found a solution to fit my needs.
Firstly, I completely removed python 2.7 and installed back 3.10.
I tried running the script file inside the shell command line and got the same error that the modules could not be found. What I did is try to import these modules and it gave an error, specifically for bs4 that I am using packages for python 2.x instead of 3.x packages.
After futher investigation I discovered that the packages that I have for my script are treated as "local" packages, meaning I installed them from the IDE (PyCharm) and they work for that project only I guess.
I also found that to "globally" access these packages I had to install them through the command line using the pip3 install <package_name>. After doing this the problem was gone and was left with running the script from the Windows Forms.
NOTE: I did not manage to start the script using python.exe, so I used bash script for the job.
Here is my code and I hope it helps someone down the line...
Code in C#
string myApp = string.Format("{0} {1}", @"C:\testing1.sh", "Hello");
var processStartInfo = new ProcessStartInfo
{
Arguments = myApp,
FileName = "C:\\Program Files\\Git\\git-bash.exe",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false
};
Process.Start(processStartInfo)
Code in Bash Script File
#!/bin/bash
arg1="$1"
python C:/Users/Dobromir/PycharmProjects/testing/main.py "$arg1"
Inside the Python file I am using sys.argv[] and accessing the arguments.
NOTE: Passing arguments from the bash script to the python script, in this case, you will receive 2 arguments - first one is the path to the python file and the second is the variable arg1.
Another important thing to mention is you need to have comas around the $1 - this is the property that is being send from the C# file, else it will show as empty.
Articles that were useful:
Installed BeautifulSoup but still get no module named bs4
Passing arguments to Python from Shell Script
https://unix.stackexchange.com/questions/31414/how-can-i-pass-a-command-line-argument-into-a-shell-script
https://gist.github.com/creativcoder/6df4d349447ff1416e68
Thank you to everyone who contributed and tried to help, I managed to learned new things with your suggestions!
Python.Net - How to run python script from file(.Py)
Finally i ended up with the following solution.
using (Py.GIL()){
dynamic os = Py.Import("os");
dynamic sys = Py.Import("sys");
sys.path.append(os.path.dirname(os.path.expanduser(filePath)));
var fromFile = Py.Import(Path.GetFileNameWithoutExtension(filePath));
fromFile.InvokeMethod("replace");
}
Related Topics
How to Find the Text Within a Div in the Source of a Web Page Using C#
Proper Use of the Idisposable Interface
How to Dynamically Compile and Execute C# Code Fragments
Deserialize Json Object into Dynamic Object Using Json.Net
Is There a String Math Evaluator in .Net
A Field Initializer Cannot Reference the Nonstatic Field, Method, or Property
Json.Net Error Self Referencing Loop Detected For Type
C# Httpclient 4.5 Multipart/Form-Data Upload
Difference Between Const and Readonly in C#
How to Convert HTML to Text in C#
Send Http Post Request in .Net
The Entity Cannot Be Constructed in a Linq to Entities Query
Pass Method as Parameter Using C#
How to Make the Script Wait/Sleep in a Simple Way in Unity
In C#, Should I Use String.Empty or String.Empty or "" to Intitialize a String