I have been trying for hours to figure out how to do this but I have a python script that was made into an exe so it acts a console application I'm trying to write a GUI wrapper for it using WPF I have it set up to where it does execute the exe with the command arguments but I want to capture the output from the console and display it in a text box and i can not figure it out. I have tried multiple code snippets but it either does nothing, Outputs after the python exe has finished, or locks up the GUI until the python exe finishes then dumps the completed output to the textbox.
Would someone be able to take a look and see if they can help me with this?
public partial class MainWindow : Window
{
//string output = string.Empty;
private static StringBuilder output = new StringBuilder();
private object syncGate = new object();
private Process process;
private bool outputChanged;
public MainWindow()
{
InitializeComponent();
}
private void RB_Mii_Checked(object sender, RoutedEventArgs e)
{
}
//If we click the button we copy the bin file to the work directory
private void btn_SelMiiQR_Click(object sender, RoutedEventArgs e)
{
//Copy the encrypted.bin file to the working directory
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Input.bin (*.bin)|*.bin|All files (*.*)|*.*";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (openFileDialog.ShowDialog() == true)
{
var fileName = openFileDialog.FileName;
String exePath = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName;
//If the file exists delete the existing file and copy the newone.
if (System.IO.File.Exists(System.IO.Path.GetDirectoryName(exePath) + "\\App\\" + System.IO.Path.GetFileName(fileName)))
{
System.IO.File.Delete(System.IO.Path.GetDirectoryName(exePath) + "\\App\\" + System.IO.Path.GetFileName(fileName));
}
System.IO.File.Copy(fileName, System.IO.Path.GetDirectoryName(exePath) + "\\App\\" + System.IO.Path.GetFileName(fileName));
}
}
//If the button was clicked use the input.bin file and attempt to brute force the movable_sedpart1.bin
private void BTN_MIIBF_Click(object sender, RoutedEventArgs e)
{
//If the mfg has input year or no input use it
if (TB_MFGYR.Text.Length == 0 || TB_MFGYR.Text.Length == 4)
{
string DStype = null;
string MFGYR = null;
//Grab the Year if it has value
if (TB_MFGYR.Text.Length == 4)
{
MFGYR = TB_MFGYR.Text;
}
else
{
MFGYR = null;
}
if (RB_N3ds.IsChecked == true)
{
DStype = "new";
}
else if (RB_O3DS.IsChecked == true)
{
DStype = "old";
}
//Execute Command with Arguments
String exePath = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName;
string dir = System.IO.Path.GetDirectoryName(exePath)+"\\App\\";
//Start the process and export thr console output to the textbox
CreateProcess(dir + "seedminer_launcher.exe", "Mii " + DStype + " " + MFGYR, dir);
}
//Else display Error Message WIP
else
{
tb_outputtext.Text = null;
tb_outputtext.Text = "MFG Year must have 4 characters or none";
}
}
//Execute a new process
private void CreateProcess(string fileName, string arguments, string workdir)
{
// Process process = new Process();
process = new Process();
process.StartInfo.FileName = fileName;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = workdir;
process.OutputDataReceived += proc_OutputDataReceived;
process.Start();
process.BeginOutputReadLine();
}
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
this.Dispatcher.Invoke((Action)(() =>
{
tb_outputtext.Text = tb_outputtext.Text + "\n" + e.Data;
tb_outputtext.ScrollToEnd();
}));
}
private void ReadData()
{
var input = process.StandardOutput;
int nextChar;
while ((nextChar = input.Read()) >= 0)
{
lock (syncGate)
{
output.Append((char)nextChar);
if (!outputChanged)
{
outputChanged = true;
var dispatcher = Application.Current.MainWindow.Dispatcher;
Dispatcher.BeginInvoke(new Action(OnOutputChanged));
}
}
}
lock (syncGate)
{
process.Dispose();
process = null;
}
}
private void OnOutputChanged()
{
lock (syncGate)
{
tb_outputtext.AppendText(output.ToString());
outputChanged = false;
}
}
}