Execute Python code from C # GUI

Introduction

It is an extension of Execute Python script from C # GUI application, and it is said that the python source code input directly from the GUI can be executed.

What I made

The screen is as follows. The screen shows the result of executing the calculation by numpy. image.png

If the grammar is different, the following error will be displayed. image.png

Source

I just saved the user-entered Python code as a python script in a temporary folder and let pytnon.exe execute it, nothing technically new.

However, it's fun to be able to freely enter and execute python code on the spot.

As an application example that came to my mind, I think it can be used when distributing Python code that you absolutely do not want to see.

Finally, the source is described. Please refer to Running Python script from C # GUI application for the explanation.

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace PythonExecutor
{

    public partial class Form1 : Form
    {
        private Process currentProcess;
        private StringBuilder outStringBuilder = new StringBuilder();
        private int readCount = 0;
        private Boolean isCanceled = false;
        private String pythonFileName = "temporaryPythonFile.py";
        
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        ///Add string to Textbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void AppendText(String data, Boolean console)
        {
            textBox1.AppendText(data);
            if (console)
            {
                textBox1.AppendText("\r\n");
                Console.WriteLine(data);
            }
        }

        /// <summary>
        ///Behavior when the execute button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            if (Directory.Exists(this.textBox3.Text.Trim()))
            {
                //Write to python file in work folder
                String path = this.textBox3.Text.Trim() + System.IO.Path.DirectorySeparatorChar + this.pythonFileName;

                using (StreamWriter writer = new StreamWriter(path))
                {
                    StringReader strReader = new StringReader(this.textBox4.Text.Trim());
                    while (true)
                    {
                        String aLine = strReader.ReadLine();
                        if (aLine != null)
                        {
                            writer.WriteLine(aLine);

                        }
                        else
                        {
                            break;
                        }
                    }
                    writer.Close();
                }

                //Preprocessing
                button1.Enabled = false;
                button2.Enabled = true;
                isCanceled = false;
                readCount = 0;
                outStringBuilder.Clear();
                this.Invoke((MethodInvoker)(() => this.textBox1.Clear()));

                //Run
                RunCommandLineAsync(path);
            }
            else
            {
                this.Invoke((MethodInvoker)(() => MessageBox.Show("Working folder is invalid")));
            }

        }

        /// <summary>
        ///Command execution process body
        /// </summary>
        public void RunCommandLineAsync(String pythonScriptPath)
        {

            ProcessStartInfo psInfo = new ProcessStartInfo();
            psInfo.FileName = this.textBox2.Text.Trim();
            psInfo.WorkingDirectory = this.textBox3.Text.Trim();
            // psInfo.Arguments = this.textBox4.Text.Trim();
            psInfo.Arguments = pythonScriptPath;

            psInfo.CreateNoWindow = true;
            psInfo.UseShellExecute = false;
            psInfo.RedirectStandardInput = true;
            psInfo.RedirectStandardOutput = true;
            psInfo.RedirectStandardError = true;

            // Process p = Process.Start(psInfo);
            Process p = new System.Diagnostics.Process();
            p.StartInfo = psInfo;
          
            p.EnableRaisingEvents = true;
            p.Exited += onExited;
            p.OutputDataReceived += p_OutputDataReceived;
            p.ErrorDataReceived += p_ErrorDataReceived;

            p.Start();


            //Start reading output and error asynchronously
            p.BeginOutputReadLine();
            p.BeginErrorReadLine();

            currentProcess = p;
        }

        void onExited(object sender, EventArgs e)
        {
            int exitCode;

            if (currentProcess != null)
            {
                currentProcess.WaitForExit();

                //Exhaling data that remains without being exhaled
                this.Invoke((MethodInvoker)(() => AppendText(outStringBuilder.ToString(), false)));
                outStringBuilder.Clear();

                exitCode = currentProcess.ExitCode;
                currentProcess.CancelOutputRead();
                currentProcess.CancelErrorRead();
                currentProcess.Close();
                currentProcess.Dispose();
                currentProcess = null;

                //Delete python file
                String pythonFilepath = this.textBox3.Text.Trim() + System.IO.Path.DirectorySeparatorChar + this.pythonFileName;
                if (File.Exists(pythonFilepath)) ;
                {
                    File.Delete(pythonFilepath);
                }

                this.Invoke((MethodInvoker)(() => this.button1.Enabled = true));
                this.Invoke((MethodInvoker)(() => this.button2.Enabled=false));

                if (isCanceled)
                {
                    //Completion message
                    this.Invoke((MethodInvoker)(() => MessageBox.Show("Canceled processing")));
                }
                else
                {
                    if (exitCode == 0)
                    {
                        //Completion message
                        this.Invoke((MethodInvoker)(() => MessageBox.Show("Processing is complete")));
                    }
                    else
                    {
                        //Completion message
                        this.Invoke((MethodInvoker)(() => MessageBox.Show("An error has occurred")));
                    }
                }
            }
        }

        /// <summary>
        ///Processing when standard output data is received
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void p_OutputDataReceived(object sender,
            System.Diagnostics.DataReceivedEventArgs e)
        {
            processMessage(sender, e);
        }

        /// <summary>
        ///What to do when a standard error is received
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void p_ErrorDataReceived(object sender,
            System.Diagnostics.DataReceivedEventArgs e)
        {
            processMessage(sender, e);
        }

        /// <summary>
        ///Receives CommandLine program data and spits it into a TextBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void processMessage(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            if (e != null && e.Data != null && e.Data.Length > 0)
            {
                outStringBuilder.Append(e.Data + "\r\n");
            }
            readCount++;
            //Exhale at a cohesive timing
            if (readCount % 5 == 0)
            {
                this.Invoke((MethodInvoker)(() => AppendText(outStringBuilder.ToString(), false)));
                outStringBuilder.Clear();
                //Put sleep to not occupy threads
                if (readCount % 1000 == 0)
                {
                    Thread.Sleep(100);
                }
            }
        }

        /// <summary>
        ///Behavior when the cancel button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (currentProcess != null)
            {
                try
                {
                    currentProcess.Kill();
                    isCanceled = true;
                }
                catch (Exception e2)
                {
                    Console.WriteLine(e2);
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //Clear Python code part
            this.textBox4.Clear();
            //Clear standard output area
            this.textBox1.Clear();
        }
        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

2020/2/24 revised

Fixed as follows because there was a fatal bug that started the process twice. We apologize for the inconvenience.

// Process p = Process.Start(psInfo); Process p = new System.Diagnostics.Process(); p.StartInfo = psInfo;

Recommended Posts

Execute Python code from C # GUI
Execute Python code on C ++ (using Boost.Python)
[Note] Execute Python code from Excel (xlwings)
Execute command from python
Run a Python script from a C # GUI application
I want to make C ++ code from Python code!
Stop Omxplayer from Python code
Execute Python script from batch file
Call popcount from Ruby / Python / C #
Execute C ++ functions from Python with Pybind11 (for Windows & Visual Studio Code people) Debugging
Run Python scripts synchronously from C #
Call C / C ++ from Python on Mac
Call c language from python (python.h)
Execute C ++ functions from Python with Pybind11 (for Windows & Visual Studio Code people) Environment construction
Enumerate duplicate combinations (C ++) → Add Python code
Generate C language from S-expressions in Python
Use C ++ functions from python with pybind11
sql from python
python C ++ notes
python, openFrameworks (c ++)
[Python] Algorithm-aware code
Build an environment to execute C ++ functions from Python with Pybind11 (for Windows & Visual Studio Code people)
Create a C array from a Python> Excel sheet
Wrap C with Cython for use from Python
Load and execute command from yml in python
[Node-RED] Execute Python on Anaconda virtual environment from Node-RED [Anaconda] [Python]
Call a Python script from Embedded Python in C ++ / C ++
Wrap C ++ with Cython for use from Python
I tried to execute Python code from .Net using Pythonnet (Hallo World edition)
Use thingsspeak from python
[Python] Django Source Code Reading View Starting from Zero ①
Touch MySQL from Python 3
Reading CSV data from DSX object storage Python code
Operate Filemaker from Python
Use fluentd from python
Python C / C ++ Extension Pattern-Pointer
[Unity (C #), Python] Try running Python code in Unity using IronPython
Access bitcoind from python
Changes from Python 3.0 to Python 3.5
Changes from Python 2 to Python 3.0
Machine learning python code summary (updated from time to time)
Python from or import
Rewrite Python2 code to Python3 (2to3)
infomap python draw code
Automatically execute python file
Use MySQL from Python
Before writing Python code
Run python from excel
Install python from source
Get the return code of the Python script from bat
Next Python in C
Operate neutron from Python!
About Python3 character code
Read QR code from image file with Python (Mac)
Operate LXC from Python
Manipulate riak from python
[GUI in Python] PyQt5-Dialog-
Force Python from Fortran
Execute Python function from Powershell (how to pass arguments)
Use BigQuery from python.
I felt that I ported the Python code to C ++ 98.