Execute python from C# - c#

im trying to execute some python code from C#, so i have this code :
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\Users\protieax\PycharmProjects\untitled\venv\Scripts\python.exe";
start.Arguments = "request.py 31.12.2016 01.01.2017 datatype"; // give filename, dates from the UI to python and query datatype
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
It should work but the C# doesnt find the python file.
What i should put in those 2 variables? Thanks
EDIT :
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"U:\Documents\entsoe-py-master\tests\test_data";
start.Arguments = "request.py 31.12.2016 01.01.2017 datatype"; // give filename, dates from the UI to python and query datatype
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
Console.Write(result);
}
}
Here is my code modified with your answers. I have a new error :
System.ComponentModel.Win32Exception: 'The system cannot find the file specified'
At the line
using (Process process = Process.Stqrt(start))

You specified a U drive, presumably a network drive. I've never used a network drive in a context like this one but I tried it to find out if that's the problem. I mounted a network drive with U being the label. After running the code, it failed and gave me the same error. I advise making a copy of the desired python script into your current working directory instead, it would make things a lot more simple.

Related

Exception "The requested operation requires elevation" when i run my .net code

"I'm trying to execute "main.py" file which is written in Python by my .net core web API but i got an exception.
I already give the permission of my Web API folder as well as my Python Code folder.
var file = Configuration.GetValue<string>("DE.PythonPath");
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = file;
start.Arguments = string.Format("{0} {1}", cmd, args);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
string stderr = process.StandardError.ReadToEnd();
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return result;
}
}
I expect the python code run but it gives exception "The requested operation requires elevation"
Visual studio need to be run as admin. So run the Visual studio as Run as Administrator

P4 edit not appearing to work from c# process call no error or standard output returned

I am trying to checkout some files from p4 using a cmd process call from c# but the edit command does not seem to be working. I can change the edit to the set command and get the expected results. The edit command does not return an error or standard output. If I put a working file path in the code I get the same result. The command works from a dos box if I type it in manually. I am trying to do this without the p4 net.api if possible.
Is there anything I am missing in the code below?
System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
proc.FileName = #"c:\windows\system32\cmd.exe";
proc.Arguments = #" /c p4 edit";
proc.RedirectStandardError = true;
proc.RedirectStandardOutput = true;
proc.UseShellExecute = false;
using (System.Diagnostics.Process process = System.Diagnostics.Process.Start(proc))
{
using (StreamReader reader = process.StandardError)
{
string result = reader.ReadToEnd();
_threadError = result;
}
}
I have also tried passing a file in the following way and get the same result as above. I would expect to at least get a standard error if not a standard output.
string Arguments = string.Format(" //c p4 edit -c default {0}", _tmp);

Activating conda environment from c# code (or what is the differences between manually opening cmd and opening it from c#?)

I want to run a gpu accelerated python script on windows using conda environment (dlwin36).
I’m trying to activate dlwin36 and execute a script:
1) activate dlwin36
2) set KERAS_BACKEND=tensorflow
3) python myscript.py
If I manually open cmd on my machine and write:"activate dlwin36"
it works.
But when I try opening a cmd from c# I get:
“activate is not recognized as an internal or external command, operable program or batch file.”
I tried using the following methods:
Command chaining:
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&python myscript.py";
Process.Start(start).WaitForExit();
(I’ve tested several variations of UseShellExecute, LoadUserProfile and WorkingDirectory)
Redirect standard input:
var commandsList = new List<string>();
commandsList.Add("activate dlwin36");
commandsList.Add("set KERAS_BACKEND=tensorflow");
commandsList.Add("python myscript.py");
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.UseShellExecute = false;
start.RedirectStandardInput = true;
var proc = Process.Start(start);
commandsList.ForEach(command => proc.StandardInput.WriteLine(command));
(I’ve tested several variations of LoadUserProfile and WorkingDirectory)
In both cases, I got the same error.
It seems that there is a difference between manually opening cmd and opening it from c#.
The key is to run activate.bat in your cmd.exe before doing anything else.
// Set working directory and create process
var workingDirectory = Path.GetFullPath("Scripts");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
UseShellExecute = false,
RedirectStandardOutput = true,
WorkingDirectory = workingDirectory
}
};
process.Start();
// Pass multiple commands to cmd.exe
using (var sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
// Vital to activate Anaconda
sw.WriteLine("C:\\PathToAnaconda\\anaconda3\\Scripts\\activate.bat");
// Activate your environment
sw.WriteLine("activate your-environment");
// Any other commands you want to run
sw.WriteLine("set KERAS_BACKEND=tensorflow");
// run your script. You can also pass in arguments
sw.WriteLine("python YourScript.py");
}
}
// read multiple output lines
while (!process.StandardOutput.EndOfStream)
{
var line = process.StandardOutput.ReadLine();
Console.WriteLine(line);
}
You need to use the python.exe from your environment. For example:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\path-to-Anaconda3\envs\tensorflow-gpu\python.exe";
or in your case:
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&\"path-to-Anaconda3\envs\tensorflow-gpu\python.exe\" myscript.py";
I spent a bit of time working on this and here's the only thing that works for me: run a batch file that will activate the conda environment and then issue the commands in python, like so. Let's call this run_script.bat:
call C:\Path-to-Anaconda\Scripts\activate.bat myenv
set KERAS_BACKEND=tensorflow
python YourScript.py
exit
(Note the use of the call keyword before we invoke the activate batch file.)
After that you can run it from C# more or less as shown above.
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/K c:\\path_to_batch\\run_script.bat";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.WorkingDirectory = "c:\\path_to_batch";
string stdout, stderr;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
stdout = reader.ReadToEnd();
}
using (StreamReader reader = process.StandardError)
{
stderr = reader.ReadToEnd();
}
process.WaitForExit();
}
I am generating the batch file on the fly in C# to set the necessary parameters.
If this is gonna help anyone in the future. I found that you must run the activation from C:\ drive.

Unable to run python script in c# which runs scrapy spider

I followed this_link and I was able to run a dummy python file from my c# code like this...
public JsonResult FetchscrapyDataUrl(String website)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\ProgramData\Anaconda3\python.exe";
start.Arguments = #"C:\Users\PycharmProjects\scraping_web\scrape_info\main.py";
//this is path to .py file from scrapy project
start.CreateNoWindow = false; // We don't need new window
start.UseShellExecute = false; // Do not use OS shell
//start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
Console.WriteLine("Python Starting");
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
Console.Write(result);
}
}
}
Now I know that I can run scrapy spider from a single file main.py like this...
from scrapy import cmdline
cmdline.execute("scrapy crawl text".split())
When I run main.py file from cmd in windows it works fine but it does not work when I run it from C# code .Net framework. The error is ...
"Scrapy 1.4.0 - no active project\r\n\r\nUnknown command: crawl\r\n\r\nUse \"scrapy\" to see available commands\r\n"
Any Idea how to run this...Or am i missing some path setting in windows ??
Or should I run my spider from C# in some other way??
You need to set the WorkingDirectory property
start.WorkingDirectory = #"C:\Users\PycharmProjects\scraping_web\scrape_info\"
Or you need to cd to that directory to make it work

C# Process.StandardError reading without blocking

I am a programming teacher and I am developing an automated checker for the students HWs (All are Console Apps). Basically, I run the student code using some Process.Start() (with some input file) and check if its output is as expected.
If, for some reason, the student code did no complete succesfully, I send them the exception thrown by their code using the process Standart Error redirection.
However, I want to do better then that. I want to find the input line written to the process StandartInput afterwhich their exception took place. How can I do that? My current code is more or less:
ProcessStartInfo psi = new ProcessStartInfo(students_exe_path);
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
String randomInputFile = randomInputFilesFolder + "\\" + "test.txt";
psi.WorkingDirectory = randomInputFilesFolder;
Process p = Process.Start(psi);
StreamWriter inputWriter = p.StandardInput;
String[] inputLines = File.ReadAllLines(randomInputFile);
foreach (String line in inputLines)
{
// here I wanted to read the standart error so far (before writing next input line)
String errorTextBefore = p.StandardError.ReadToEnd(); // can not use this because blocks progress.
inputWriter.WriteLine(line); // sending next input line to students app
// here I wanted to read the standart error so far (after writing next input line)
String errorTextAfter = p.StandardError.ReadToEnd(); // can not use because blocks
if (errorTextBefore != errorTextAfter) Console.WriteLine("Line {0} caused the exception",line);
}
Or maybe I can check from p.StandartInput which text was not "consumed" by the process?
Tamir

Categories