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.
The screen is as follows. The screen shows the result of executing the calculation by numpy.
If the grammar is different, the following error will be displayed.
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)
{
}
}
}
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;