BrawlBuilder.BrawlBuilder.DoWit C# (CSharp) Method

DoWit() private method

private DoWit ( ProcessStartInfo pStartInfo, bool forceNoProgress = false, bool finalize = false ) : bool
pStartInfo ProcessStartInfo
forceNoProgress bool
finalize bool
return bool
		private bool DoWit(ProcessStartInfo pStartInfo, bool forceNoProgress = false, bool finalize = false)
		{
			// Determine if we want wit to be hidden or not
			if (!_showWit && !forceNoProgress)
			{
				// Set up blinker
				_progress = 0;
				_progressMax = 100;
				if (blinker.IsBusy)
				{
					blinker.CancelAsync();
					while (blinker.IsBusy)
					{
						Thread.Sleep(100);
					}
				}
				blinker.RunWorkerAsync();

				// Create outside of loop for better performance
				Regex r = new Regex(@"(\d+)%");

				using (Process p = Process.Start(pStartInfo))
				{
					using (StreamReader reader = p.StandardOutput)
					{
						while (!p.HasExited)
						{
							reader.DiscardBufferedData();

							string curStatus = reader.ReadLine();

							if (curStatus == null)
							{
								// Wit has probably exited, but we'll try to loop through again after a short sleep.
								Thread.Sleep(100);
								continue;
							}

							Match m = r.Match(curStatus);

							if (m.Groups.Count > 1)
								_progress = int.Parse(m.Groups[1].Value);

							// During build 99% can stay up for a loooong time depending on drive speed, so switch status to Finalizing...
							if (_progress >= 99 && finalize)
							{
								blinker.CancelAsync();
								while (blinker.IsBusy)
									Thread.Sleep(100);

								SetStatus("Finalizing...");
								finalize = false; // No need to keep setting it, once is enough
							}

							if (buildWorker.CancellationPending)
							{
								// Stop blinker
								blinker.CancelAsync();

								// Kill process
								if (!p.HasExited)
								{
									p.Kill();
									p.WaitForExit();
								}

								// Didn't finish working, delete ssbb.d
								DeleteBrawlFolder();

								return false;
							}

							Thread.Sleep(100);
						}
					}

					string error = "";
					using (StreamReader s = p.StandardError)
					{
						error = s.ReadToEnd();
					}

					// Check wit exit code
					if (p.ExitCode != 0)
					{
						StopWorker("Wit closed unexpectedly with exit code " + p.ExitCode + ", stopping build..." + (error.Length > 0 ? "\n\nWit error messages:\n\n" + error : ""), error.Length > 0);
					}
					// If there were errors, but exit code was fine, notify the user, but let them continue
					else if (error.Length > 0)
					{
						DialogResult result = FlexibleMessageBox.Show("Wit didn't exit with an error code, however it did write to the error output with the following:\n\n" + error + "\n\nDo you still want to continue the build?", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

						if (result == DialogResult.No)
							buildWorker.CancelAsync();
					}
				}
			}
			else
			{
				// Check if we want to keep the window open after, and handle that if we do
				if (Environment.GetCommandLineArgs().Contains("--show-wit-debug"))
				{
					ProcessStartInfo newStartInfo = new ProcessStartInfo();
					newStartInfo.FileName = "CMD.exe";
					newStartInfo.Arguments = "/C \"\"" + pStartInfo.FileName + "\" " + pStartInfo.Arguments + " & pause & if errorlevel 1 exit -1\"";
					pStartInfo = newStartInfo;
				}

				using (Process p = Process.Start(pStartInfo))
				{
					p.WaitForExit();

					if (p.ExitCode != 0)
					{
						if (Environment.GetCommandLineArgs().Contains("--show-wit-debug"))
						{
							// The exit code won't be accurate, so just say Wit closed
							StopWorker("Wit closed unexpectedly, stopping build...");
						}
						else
						{
							StopWorker("Wit closed unexpectedly with exit code " + p.ExitCode + ", stopping build...");
						}
					}
				}
			}

			// Stop blinker before continuing
			blinker.CancelAsync();
			while (blinker.IsBusy)
				Thread.Sleep(100);

			if (buildWorker.CancellationPending)
			{
				// Didn't finish working, delete ssbb.d
				DeleteBrawlFolder();

				return false;
			}

			return true;
		}