//load the commands list with basic descriptions public async void LoadCommands() { Process TmpProcess = new Process(); TmpProcess.StartInfo.FileName = PM3FileName; // Specify exe name. TmpProcess.StartInfo.Arguments = "-h"; TmpProcess.StartInfo.UseShellExecute = false; TmpProcess.StartInfo.RedirectStandardOutput = true; TmpProcess.Start(); string CommandsList = TmpProcess.StandardOutput.ReadToEnd(); Commands.Clear(); using (StringReader sr = new StringReader(CommandsList)) { bool StartParse = false; string line; while ((line = sr.ReadLine()) != null) { if (line.IndexOf("command") == 0) { StartParse = true; } if (!StartParse) { continue; } if (line.IndexOf("command") == 0 || line.IndexOf("-------") >= 0) { continue; } if (line.IndexOf("###") == 0) { Commands.Add(new PM3Command(line.Replace("###", "").Trim(), "")); } else if (line.IndexOf('|') > 0) { PM3Command cmd = new PM3Command((line.Split('|')[0]).Trim(), (line.Split('|')[2]).Trim()); Commands.Add(cmd); } else if (line.IndexOf('{') > 0 && line.IndexOf('}') > 0) { Commands.Last().Description = line.Substring(line.IndexOf('{') + 1, line.IndexOf('}') - line.IndexOf('{') - 2).Trim(); } } } }
private void textBox1_TextChanged(object sender, EventArgs e) { if (PM3CommandsTree.SelectedNode == null || PM3CommandsTree.SelectedNode.Tag == null) { return; } int ItemIndex = (int)PM3CommandsTree.SelectedNode.Tag; //156 if (ItemIndex < 0 || ItemIndex >= Program.PM3.Commands.Count) { return; } PM3Command cmd = Program.PM3.Commands[ItemIndex]; commandComboBox.Text = cmd.Command; commandComboBox.Text += GenerateCommand(CommandParamsContainer, cmd); }
private void btnReloadCommands_Click(object sender, EventArgs e) { Program.PM3.LoadCommands(3); if (Program.PM3.Commands.Count == 0) { Program.PM3.LoadCommands(4); } PM3CommandsTree.Nodes.Clear(); PM3CommandsTree.Nodes.Add("PM3"); for (int cIndex = 0; cIndex < Program.PM3.Commands.Count; cIndex++) { PM3Command c = Program.PM3.Commands[cIndex]; string[] path = c.Command.Split(' '); TreeNode n = PM3CommandsTree.Nodes[0]; for (int i = 0; i < path.Count(); i++) { if (n.Nodes.ContainsKey(path[i])) { n = n.Nodes[path[i]]; } else { TreeNode t = new TreeNode(path[i]); t.Tag = cIndex; t.Name = t.Text; t.Text += " (" + c.Description + ")"; if (i == path.Count() - 1) { t.ToolTipText = c.Description; } n.Nodes.Add(t); n = t; } } } PM3CommandsTree.Nodes[0].Expand(); }
private string GenerateCommand(Control c, PM3Command cmd) { string Result = ""; foreach (Control child in c.Controls) { if (child.GetType() == typeof(GroupBox)) { Control c2 = child.Controls[0]; if (c2.GetType() == typeof(CheckBox)) { if (c2.Top == 0) { if (!((CheckBox)c2).Checked) { continue; } } } } if (child.GetType() == typeof(CheckBox)) { if (!((CheckBox)child).Checked) { continue; } } if (child.GetType() == typeof(RadioButton)) { if (!((RadioButton)child).Checked) { continue; } } Result += GenerateCommand(child, cmd); } if (c.Controls.Count > 0) { return(Result); } if (c.GetType() == typeof(CheckBox)) { if (!((CheckBox)c).Checked) { return(Result); } } if (c.GetType() == typeof(RadioButton)) { if (!((RadioButton)c).Checked) { return(Result); } } if (c.Tag != null) { PM3CommandParam p = cmd.Params[(int)c.Tag]; if (c.GetType() == typeof(TextBox)) { Result += " " + c.Text; } else if (c.GetType() == typeof(ComboBox)) { if (((ComboBox)c).SelectedItem != null) { Result += " " + ((PM3CommandParamAllowedValue)((ComboBox)c).SelectedItem).Value; } } else { Result += " " + p.Name; } } return(Result); }
private void PM3CommandsTree_AfterSelect(object sender, TreeViewEventArgs e) { if (e == null || e.Node.Tag == null) { return; } int ItemIndex = (int)e.Node.Tag; //156 if (ItemIndex < 0 || ItemIndex >= Program.PM3.Commands.Count) { return; } PM3Command cmd = Program.PM3.Commands[ItemIndex]; commandComboBox.Text = cmd.Command; if (cmd.DescriptionFull == null) { Program.PM3.ExtractCommandParams(cmd); } CommandParamsContainer.Controls.Clear(); CommandDescriptionTextBox.Text = ""; if (cmd.DescriptionFull != null) { AppendText(CommandDescriptionTextBox, Color.FromArgb(255, 224, 224, 224), cmd.DescriptionFull + "\r\n", false, true); } if (cmd.Usage != null) { AppendText(CommandDescriptionTextBox, Color.FromArgb(255, 192, 192, 255), cmd.Usage + "\r\n", true); } if (cmd.Options != null) { AppendText(CommandDescriptionTextBox, Color.FromArgb(255, 128, 128, 255), cmd.Options + "\r\n"); } if (cmd.Examples != null) { AppendText(CommandDescriptionTextBox, Color.FromArgb(255, 255, 128, 0), cmd.Examples + "\r\n", false, true); } CommandDescriptionTextBox.SelectionStart = 0; CommandDescriptionTextBox.SelectionLength = 0; CommandDescriptionTextBox.ScrollToCaret(); Control PreviousControl = null; for (int i = 0; i < cmd.Params.Count; i++) { PM3CommandParam p = cmd.Params[i]; Control Container = CommandParamsContainer; //by default adding new controls directly to the container. Otherwise - inside the checkbox or radio button Control c = null; //if the option should be placed into a group box if (p.GroupWithNext || (i > 0 && (cmd.Params[i - 1].GroupWithNext))) { GroupBox GroupContainer = null; int cTop = 0; //this is the first option in a group -> create a groupbox container if (i == 0 || (i > 0 && !(cmd.Params[i - 1].GroupWithNext))) { GroupContainer = new System.Windows.Forms.GroupBox(); CommandParamsContainer.Controls.Add(GroupContainer); if (p.IsOptional) { CheckBox EnableGroup = new System.Windows.Forms.CheckBox(); EnableGroup.Width = EnableGroup.Height; EnableGroup.CheckedChanged += textBox1_TextChanged; GroupContainer.Controls.Add(EnableGroup); } } else //continue adding options to the group box created before { Control PreviousRow = PreviousControl; if (PreviousRow.GetType() != typeof(RadioButton) && PreviousRow.GetType() != typeof(CheckBox) && PreviousRow.GetType() != typeof(Panel)) { PreviousRow = PreviousControl.Parent; } Control PreviousGroupBox = PreviousRow.Parent; if (PreviousGroupBox.GetType() != typeof(GroupBox)) { PreviousGroupBox = PreviousGroupBox.Parent; } GroupContainer = (GroupBox)PreviousGroupBox; cTop = PreviousRow.Top + PreviousRow.Height; } if (p.OrWithNext || (i > 0 && (cmd.Params[i - 1].OrWithNext))) // [x|y] { Container = new System.Windows.Forms.RadioButton(); } else //[x <y>] { Container = new System.Windows.Forms.Panel(); Container.Height = TextRenderer.MeasureText("^_|", Container.Font).Height * 2; } Container.Top = cTop; // + Container.Height / 4; if (cTop == 0) { Container.Top += Container.Height; } Container.Width = GroupContainer.Width * 9 / 10; Container.Left = GroupContainer.Width * 1 / 20; GroupContainer.Controls.Add(Container); GroupContainer.Height = Container.Top + Container.Height + Container.Height / 4; } if (p.IsOptional) { if ((Container.GetType() == typeof(GroupBox)) || (Container.GetType() == typeof(FlowLayoutPanel))) { Control CheckBoxContainer = new System.Windows.Forms.CheckBox(); Container.Controls.Add(CheckBoxContainer); Container = CheckBoxContainer; } } if (( (p.ParamType == PM3CommandParam.EParamType.Fixed) || (p.ParamType == PM3CommandParam.EParamType.Flag && p.GroupWithNext) ) && ( (Container.GetType() == typeof(GroupBox)) || (Container.GetType() == typeof(FlowLayoutPanel)) || (Container.GetType() == typeof(Panel)) )) { c = new System.Windows.Forms.Label(); ((Label)c).TextAlign = ContentAlignment.MiddleLeft; ((Label)c).AutoEllipsis = true; Container.Controls.Add(c); } else if (p.AllowedValues.Count > 0) { c = new System.Windows.Forms.ComboBox(); c.Enter += textBox1_Enter; Container.Controls.Add(c); } else if ((p.ParamType == PM3CommandParam.EParamType.Value) || (p.Description == null)) { c = new System.Windows.Forms.TextBox(); c.Enter += textBox1_Enter; Container.Controls.Add(c); } else if ((Container.GetType() != typeof(GroupBox)) && (Container.GetType() != typeof(FlowLayoutPanel))) { c = Container; c.Enter += textBox1_Enter; } if (Container.GetType() == typeof(RadioButton) || Container.GetType() == typeof(CheckBox)) { if (c != Container) { c.Left += c.Height; c.Width = Container.Width - c.Left; Container.Enter += textBox1_Enter; if (Container.GetType() == typeof(RadioButton)) { ((RadioButton)Container).CheckedChanged += textBox1_TextChanged; } if (Container.GetType() == typeof(CheckBox)) { ((CheckBox)Container).CheckedChanged += textBox1_TextChanged; } } } c.Text = p.Name; if (p.Description != null) { c.Text += " (" + p.Description + ")"; } defaultToolTip.SetToolTip(c, c.Text); c.Tag = i; Container.Tag = i; foreach (PM3CommandParamAllowedValue av in p.AllowedValues) { if (c.GetType() == typeof(ComboBox)) { ((ComboBox)c).Items.Add(av); } } PreviousControl = c; if (c.GetType() == typeof(RadioButton)) { ((RadioButton)c).CheckedChanged += textBox1_TextChanged; } if (c.GetType() == typeof(CheckBox)) { ((CheckBox)c).CheckedChanged += textBox1_TextChanged; } if (c.GetType() == typeof(TextBox) || c.GetType() == typeof(ComboBox)) { c.TextChanged += textBox1_TextChanged; } } ResizeFit(CommandParamsContainer, 300); }
//load the commands list with basic descriptions public async void LoadCommands(int version = 3) { if (!File.Exists(PM3FileName)) { throw new System.ArgumentException("Cannot find PM3 console client \"" + PM3FileName + "\". Please check that this file exists or provide an alternative location in PM3UniversalGUI.exe.config PM3ClientFilename setting.", "PM3ClientFilename"); } Process TmpProcess = new Process(); TmpProcess.StartInfo.FileName = PM3FileName; // Specify exe name. if (version >= 4) { TmpProcess.StartInfo.Arguments = "-t"; } else { TmpProcess.StartInfo.Arguments = "-h"; } TmpProcess.StartInfo.UseShellExecute = false; TmpProcess.StartInfo.RedirectStandardOutput = true; TmpProcess.Start(); string CommandsList = TmpProcess.StandardOutput.ReadToEnd(); Commands.Clear(); using (StringReader sr = new StringReader(CommandsList)) { bool StartParse = false; string line; while ((line = sr.ReadLine()) != null) { if (line.IndexOf("command") == 0) { StartParse = true; } if (!StartParse) { continue; } if (line.IndexOf("command") == 0 || line.IndexOf("-------") >= 0) { continue; } if (line.IndexOf("###") == 0) { Commands.Add(new PM3Command(line.Replace("###", "").Trim(), "")); } else if (line.IndexOf('|') > 0) { PM3Command cmd = new PM3Command((line.Split('|')[0]).Trim(), (line.Split('|')[2]).Trim()); Commands.Add(cmd); } else if (line.IndexOf('{') > 0 && line.IndexOf('}') > 0) { Commands.Last().Description = line.Substring(line.IndexOf('{') + 1, line.IndexOf('}') - line.IndexOf('{') - 2).Trim(); } } } }
//try to parse detailed help output of specific command public void ExtractCommandParams(PM3Command cmd) { Process TmpProcess = new Process(); TmpProcess.StartInfo.FileName = PM3FileName; TmpProcess.StartInfo.Arguments = "-c \"" + cmd.Command + " h\""; TmpProcess.StartInfo.UseShellExecute = false; TmpProcess.StartInfo.RedirectStandardOutput = true; TmpProcess.StartInfo.CreateNoWindow = true; TmpProcess.Start(); Task <string> t = TmpProcess.StandardOutput.ReadToEndAsync(); Task t2 = Task.WhenAny(t, Task.Delay(Int32.Parse(ConfigurationManager.AppSettings["ConsoleDumpTimeout"]))).GetAwaiter().GetResult(); if (t2.Id == t.Id) { // task completed within timeout } else { try { TmpProcess.Kill(); } catch (Exception e) { } } string Output = t.Result; cmd.Usage = null; cmd.Examples = null; cmd.DescriptionFull = null; bool OptionsBlockExpected = Output.IndexOf("Options:") > 0; using (StringReader sr = new StringReader(Output)) { int Block = -1; string RelatedTo = null; int RelatedToIndent = 0; bool UsageParsed = false; string PrevDescription = null; string PrevRelatedTo = null; int PrevIndent = 0; string line; while ((line = sr.ReadLine()) != null) { if (line.IndexOf("[!]") == 0) { continue; } if (Block == -1 && line.TrimEnd().EndsWith("> " + cmd.Command + " h")) { Block = 3; continue; } if (line.TrimStart().IndexOf("Usage:", StringComparison.CurrentCultureIgnoreCase) == 0 || line.TrimStart().IndexOf("Syntax:", StringComparison.CurrentCultureIgnoreCase) == 0) { Block = 0; } if (line.TrimStart().IndexOf("Options:", StringComparison.CurrentCultureIgnoreCase) == 0) { Block = 1; continue; } if (line.TrimStart().IndexOf("Example", StringComparison.CurrentCultureIgnoreCase) == 0) { Block = 2; } if (Block == 0) //usage { string UsageString = line.Replace("\t", "").Trim(); foreach (string ReplaceKeyword in new string[] { "Usage:", "Syntax:" }) { if (UsageString.IndexOf(ReplaceKeyword, StringComparison.CurrentCultureIgnoreCase) >= 0) { UsageString = UsageString.Remove(UsageString.IndexOf(ReplaceKeyword, StringComparison.CurrentCultureIgnoreCase), ReplaceKeyword.Length); } } if (UsageString.Length > 0) { cmd.Usage += UsageString + "\r\n"; if (!OptionsBlockExpected) { Block = 1; //if there is no explicit options block we do not expect Usage to be longer than 1 line } } } else if (Block == 1) //options { cmd.Options += line + "\r\n"; if (cmd.Usage != null && !UsageParsed) { string[] UsageParts = cmd.Usage.Trim().Replace("\r\n", " ").Split(new string[] { cmd.Command }, StringSplitOptions.RemoveEmptyEntries); string UsageString = null; if (UsageParts.Length > 0) { UsageString = UsageParts[0].Trim(); } else { UsageString = cmd.Usage.Trim(); } cmd.ParseUsage(UsageString); UsageParsed = true; } string OptionDescription = line.Trim(); int Indent = line.IndexOf(OptionDescription); if (Indent > PrevIndent && PrevDescription != null && PrevDescription != "" && RelatedTo == null) { RelatedTo = PrevDescription; RelatedToIndent = PrevIndent; } if (RelatedTo != null) { if (false ||//(line.IndexOf("\t\t\t") < 0) (OptionDescription.Replace("\t", "") == "" || !line.StartsWith(" ")) || (RelatedToIndent == Indent) || (Indent < PrevIndent)) { RelatedTo = null; } } if (PrevRelatedTo == null && RelatedTo != null) //if we've missed the option in the first line { if (RelatedTo.Split('=').Length == 2 || RelatedTo.Split('-').Length == 2) { cmd.ParseOptionDescription(RelatedTo, RelatedTo); } } cmd.ParseOptionDescription(OptionDescription, RelatedTo); if (OptionDescription.Length > 1) { if ((OptionDescription.IndexOf('*') == 0) || (OptionDescription.IndexOf(':') == OptionDescription.Length - 1) || (OptionDescription.IndexOf(" see ") > 0)) { RelatedTo = OptionDescription; RelatedToIndent = Indent; } } PrevDescription = OptionDescription; PrevIndent = Indent; PrevRelatedTo = RelatedTo; } else if (Block == 2) //examples { cmd.Examples += line.Trim() + "\r\n"; } else if (Block == 3) //description full { cmd.DescriptionFull += line.Trim() + "\r\n"; } } if (!UsageParsed && cmd.Usage != null) { string UsageString2 = cmd.Usage.Trim().Replace("\r\n", " ").Split(new string[] { cmd.Command }, StringSplitOptions.RemoveEmptyEntries)[0].Trim(); cmd.ParseUsage(UsageString2); UsageParsed = true; } } //remove most likely wrongly detected fixed keywords in the beginning of the parameters block for (int i = 0; i < cmd.Params.Count; i++) { if (cmd.Params[i].ParamType != PM3CommandParam.EParamType.Fixed) { break; } if (cmd.Params[i].Description != null) { break; //highly likely that's a real one } cmd.Params.RemoveAt(i); i--; } //remove most likely wrongly detected fixed keywords in the end of the parameters block for (int i = cmd.Params.Count - 1; i >= 0; i--) { if (cmd.Params[i].ParamType != PM3CommandParam.EParamType.Fixed) { break; } cmd.Params.RemoveAt(i); } }