1

I need to embed some python scripts in C# application. The problem is these scripts use many packages like numpy, openCV etc. I've read that Ironpython may handle such embedding but it's limited to pure Python code without any packages. It would be awesome to have such script as an object in C# app so I would call it every time I need without redundant input/output operations. Time and performance are of the essence, beacause operations are performed on data captured from camera on Python script.

Is there any way to make it?

Dawid_K
  • 141
  • 1
  • 1
  • 10

2 Answers2

3
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;

namespace App
{
    public  class Test
    {
        

        private void runScript(object sender, EventArgs e)
        {
            run_cmd();
        }

        private void run_cmd()
        {

            string fileName = @"C:\app.py";

            Process p = new Process();
            p.StartInfo = new ProcessStartInfo(@"C:\path\python.exe", fileName)
            {
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            };
            p.Start();

            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();

            Console.WriteLine(output);

            Console.ReadLine();

        }
    }
}
Yafaa
  • 307
  • 1
  • 14
  • Ok that works, but time of the opening is long as hell. Could you tell now if it's possible to get some data from that python script now? What I need to make it? – Dawid_K May 07 '21 at 14:42
  • I am not sure thought but why did'nt you make your Model into an Api then host it and send a request throght C# to the Model endpoint ,it's much easier than doing all of that. – Yafaa May 07 '21 at 15:12
  • I'm not well versed in C#. I have a task to wrap my script so other can load it in WPF. I have one more question. Is there a way to load python once (because loading time to see script results is quite big) and then just run particular scripts faster? – Dawid_K May 07 '21 at 15:21
  • Yes just take the code that call the executable in one fixed block not every time you call every script. – Yafaa May 07 '21 at 19:18
3

If you need your python script to interact with .NET objects, you might take a look at the Python.NET package.

using Python.Runtime;

class Test
{

    void RunPython()
    {
        using (Py.GIL())
        {
            using (var scope = Py.CreateScope())
            {
                var scriptFileName = "myscript.py";
                var compiledFile = PythonEngine.Compile(File.ReadAllText(scriptFileName), scriptFileName);

                scope.Execute(compiledFile); // can be compiled once, executed  multiple times.
            }
        }
    }
}

You can pass named object to the Python engine with code like this:

scope.Set("person", pyPerson);

you can find more examples, including examples how to access .NET objects here:

http://pythonnet.github.io/

Using IronPython would be another possibility, but it supports Python 2.7 syntax and is not fully compatible with some Python libraries.

yz1
  • 31
  • 1