using System; using System.Text; using System.Diagnostics; using System.IO; using System.Text.RegularExpressions; namespace Analizator9000 { /// /// Runs dealer generator and captures its output. /// class DealerWrapper { /// /// Calling user interfaces instance. /// private Form1 debugForm; /// /// Name of the input script file. /// private String scriptname; /// /// Stream to the generation results output file. /// private StreamWriter outputFile; /// /// Flag ensuring only one instance of dealer is running. /// private bool running = false; /// /// Number of lines (deals) to produce. /// private long produce = 0; /// /// Number of lines (deals) already produced. /// private long lineCount = 0; /// /// Dealer wrapper class constructor. /// /// Input script file name. /// Calling interface form. /// Number of deals to produce. public DealerWrapper(String scriptname, Form1 debugForm, long produce) { if (!File.Exists(scriptname)) { throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorFileNotFound", Form1.GetCulture()) + ": " + scriptname); } if (produce < 1) { throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorInvalidDealCount", Form1.GetCulture())); } this.scriptname = scriptname; this.debugForm = debugForm; this.produce = produce; } /// /// Sends a single line to debug field of the calling form. /// /// Message to be appended to the debug output. private void debugWriteLine(String line) { this.debugForm.addStatusLine(line); } /// /// Processes a chunk of dealer output. /// /// Output string of dealer instance. /// TRUE if dealer it still running, FALSE if null string arrived -> process ended. private bool handleData(string data) { if (data != null) { String[] dataLines = data.Split('\n'); foreach (String line in dataLines) { Match lineMatch = Regex.Match(line.Trim(), @"^n\s*(\S*)\s*e\s*(\S*)\s*s\s*(\S*)\s*w\s*(\S*)$"); if (lineMatch.Success) { this.lineCount++; this.outputFile.Write(this.lineCount); this.outputFile.WriteLine(lineMatch.Result(": ${1} ${2} ${3} ${4}")); } } int progress = ((int)(100 * this.lineCount / this.produce)); this.debugForm.setProgress(progress); this.debugWriteLine(data); return true; } return false; } /// /// Closes the output file stream. /// public void closeFile() { this.outputFile.Close(); } /// /// Delegate for process end callback invocation. /// /// Output file name. private delegate void onEndDelegate(String filename); /// /// Worker method for dealer generating. /// /// Callback to the function which takes output file name as a parameter. public void run(Action onEnd) { if (!this.running) { this.running = true; this.lineCount = 0; String filename = Utils.getFilename("deals"); this.outputFile = new StreamWriter(@"files\"+filename); ProcessStartInfo pInfo = new ProcessStartInfo(); pInfo.FileName = @"bin\dealer.exe"; pInfo.WindowStyle = ProcessWindowStyle.Hidden; pInfo.CreateNoWindow = true; pInfo.Arguments = "\"" + this.scriptname + "\""; pInfo.UseShellExecute = false; pInfo.RedirectStandardOutput = true; pInfo.RedirectStandardError = true; pInfo.StandardOutputEncoding = pInfo.StandardErrorEncoding = Encoding.UTF8; this.debugWriteLine(pInfo.FileName + " " + pInfo.Arguments); Process dealerProc = new Process(); dealerProc.StartInfo = pInfo; dealerProc.OutputDataReceived += (sender, output) => { if (output != null) { if (!this.handleData(output.Data)) { this.closeFile(); (new onEndDelegate(onEnd)).Invoke(filename); } } }; dealerProc.ErrorDataReceived += (sender, error) => { if (error != null) { this.debugWriteLine(error.Data); } }; dealerProc.Start(); dealerProc.BeginErrorReadLine(); dealerProc.BeginOutputReadLine(); } } } }