New to programming, been studying it for only a few months. I'm making a wpf application that is used to launch a few other applications (.exe's, .jar's, .ahk's) for Minecraft Speedrunning purposes.
I'm trying to figure out a way to launch these programs (primarely the MC instances) without completely freezing the WPF main window due to performance demand (The main window freezes while the MC instances are starting. It's fine after they're done/in main menu). Primary reason I want this is because the wpf application will have other functions that may be relevant to access/use during the startup-phase.
To launch the MC instances I use the cmd command MultiMC.exe -l [InstanceName]. For this I'm using Process.Start() with FileName "cmd.exe", Argument "MultiMC.exe -l [InstanceName]" and WorkingDirectory is the directory of MultiMC.exe.
I've looking into things like async and threading (like multithreading or parallell threads) and BackgroundWorker but haven't managed to make it work (although it's very possible I just didn't use async/threading correctly, I don't really understand it).
private static void processStarter(string directoryLocation, string cmdCommand)
{
ProcessStartInfo MCtask = new ProcessStartInfo();
MCtask.FileName = "cmd.exe";
MCtask.WindowStyle = ProcessWindowStyle.Hidden;
MCtask.Arguments = "/c " cmdCommand;
MCtask.RedirectStandardInput = true;
MCtask.RedirectStandardOutput = true;
MCtask.RedirectStandardError = true;
MCtask.WorkingDirectory = directoryLocation;
Process.Start(MCtask);
}
So I guess the question is 1: How do I go about starting these instances while keeping the WPF main window responsive to user, such as other button-presses; but also 2: is there a better way to go about starting these instances? Due to the "-l [InstanceName]" command that the MC launcher (MultiMC) takes, I didn't find a way around using CMD like this.
Oh and I initially translated the base for this code from python to c# in a console application, hence the RedirectStandardInput/Output/Error lines.
CodePudding user response:
You can use the System.Windows.Threading
namespace and the Thread
class.
private static void processStarter(string directoryLocation, string cmdCommand)
{
MCtask = new ProcessStartInfo();
MCtask.FileName = "cmd.exe";
MCtask.WindowStyle = ProcessWindowStyle.Hidden;
MCtask.Arguments = "/c " cmdCommand;
MCtask.RedirectStandardInput = true;
MCtask.RedirectStandardOutput = true;
MCtask.RedirectStandardError = true;
MCtask.WorkingDirectory = directoryLocation;
Thread thread = new Thread(RunProcess);
thread.Start();
}
private static void RunProcess()
{
Process proc = new Process();
proc.StartInfo = MCtask; // MCtask will need to be some sort of global variable.
proc.Start();
proc.WaitForExit();
}
There are ways to pass parameters to the thread function (so that you could pass MCtask
and it doesn't have to be global) but you can only pass an object
which has to be cast so its not a super great method in my opinion.