/// <summary> /// Decodes a commands tring and enqueues the associated Command for execution. /// </summary> /// <param name="reply">Reply context</param> /// <param name="cmdString">The command string that was received</param> public void Enqueue(Reply reply, String cmdString) { if (cmdString == null) { throw new ArgumentNullException(nameof(cmdString)); } string cmd; string args = ""; // parse cmd and args (eg. char vs "shutdown" vs "mouse:<action>[,<parameter>,<parameter>]" //"mouse:<action>[,<parameter>,<parameter>]" Match match = Regex.Match(cmdString, @"(\w+:)(.+)"); if (match.Success) { cmd = match.Groups[1].Value; args = match.Groups[2].Value; } else { cmd = cmdString; } cmd = cmd.ToUpperInvariant(); // TODO: Implement ignoreInternalCommands? if (cmdString.Length == 1) { // It's a single character, just send it by creating a SendInputCommand SendInputCommand keydownCmd = new SendInputCommand(cmdString, false, false, false, false); keydownCmd.Args = args; keydownCmd.Reply = reply; Logger.Instance.Log4.Info($"{this.GetType().Name}: Sending keydown for: {cmdString}"); executeQueue.Enqueue(keydownCmd); } else { // See if we know about this Command - case insensitive if (this[cmd.ToUpperInvariant()] != null) { // Always create a clone for enqueing (so Reply context can be independent) Command clone = (Command)((Command)this[cmd.ToUpperInvariant()]).Clone(reply); // This supports commands of the form 'chars:args'; these // commands do not need to originate in CommandTable if (string.IsNullOrEmpty(clone.Args)) { clone.Args = args; } EnqueueCommand(clone); } else { Logger.Instance.Log4.Info($"{this.GetType().Name}: Unknown command: {cmdString}"); } } }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose(bool disposing) { if (disposing) { // When the app exits we need to un-shift any modify keys that might // have been pressed or they'll still be stuck after exit SendInputCommand.ShiftKey("shift", false); SendInputCommand.ShiftKey("ctrl", false); SendInputCommand.ShiftKey("alt", false); SendInputCommand.ShiftKey("lwin", false); SendInputCommand.ShiftKey("rwin", false); if (components != null) { components.Dispose(); } if (_server != null) { // remove our notification handler _server.Notifications -= HandleSocketServerCallbacks; _server.Dispose(); } if (_client != null) { // remove our notification handler _client.Notifications -= HandleClientNotifications; _client.Dispose(); } if (_serialServer != null) { _serialServer.Notifications -= HandleSerialServerNotifications; _serialServer.Dispose(); } } base.Dispose(disposing); }
/// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing) { // When the app exits we need to un-shift any modify keys that might // have been pressed or they'll still be stuck after exit Logger.Instance.Log4.Debug("Ensuring shift key modifiers are reset..."); SendInputCommand.ShiftKey("shift", false); SendInputCommand.ShiftKey("ctrl", false); SendInputCommand.ShiftKey("alt", false); SendInputCommand.ShiftKey("lwin", false); SendInputCommand.ShiftKey("rwin", false); components?.Dispose(); if (Server != null) { // remove our notification handler Server.Notifications -= serverSocketCallbackHandler; Server.Dispose(); } if (Client != null) { // remove our notification handler Client.Notifications -= clientSocketNotificationHandler; Client.Dispose(); } if (SerialServer != null) { SerialServer.Notifications -= HandleSerialServerNotifications; SerialServer.Dispose(); } UpdateService.Instance.GotLatestVersion -= UpdateService_GotLatestVersion; } base.Dispose(disposing); }
/// <summary> /// Decodes a commands tring and enqueues the associated Command for execution. /// </summary> /// <param name="reply">Reply context</param> /// <param name="cmdString">The command string that was received</param> public void Enqueue(Reply reply, String cmdString) { if (cmdString == null) { throw new ArgumentNullException(nameof(cmdString)); } string cmd; var args = ""; // parse cmd and args (eg. char vs "shutdown" vs "mouse:<action>[,<parameter>,<parameter>]" // and "mouse:<action>[,<parameter>,<parameter>]" // These commands are handled internally as Cmd="cmd:" Args="<args>" var match = Regex.Match(cmdString, @"(\w+:)(.+)"); if (match.Success) { cmd = match.Groups[1].Value; args = match.Groups[2].Value; } else { cmd = cmdString; } cmd = cmd.ToLowerInvariant(); // TODO: Implement ignoreInternalCommands? if (cmdString.Length == 1 && ((Command)this["chars:"]).Enabled) { // Sending a single character is equivalent to a single key press of a key on the keyboard. // For example sending a will result in the A key being pressed. // 1 will result in the 1 key being pressed. There is no difference between sending a and A. // Use shiftdown:/shiftup: to simulate the pressing of the shift, control, alt, and windows keys. var siCmd = new SendInputCommand() { Vk = cmdString, Enabled = true, Reply = reply }; executeQueue.Enqueue(siCmd); } else { // See if we know about this Command - case insensitive if (this[cmd.ToLowerInvariant()] != null) { // Always create a clone for enqueing (so Reply context can be independent) var clone = (Command)((Command)this[cmd.ToLowerInvariant()]).Clone(reply); // This supports commands of the form 'chars:args'; these // commands do not need to originate in CommandTable if (string.IsNullOrEmpty(clone.Args)) { clone.Args = args; } EnqueueCommand(clone); } else { Logger.Instance.Log4.Info($"{this.GetType().Name}: Unknown command: {cmdString}"); } } }
public void Execute(Reply reply, String cmd) { if (!MainWindow.MainWnd.Settings.DisableInternalCommands) { if (cmd.StartsWith(McecCommand.CmdPrefix)) { var command = new McecCommand(cmd); command.Execute(reply); return; } if (cmd.StartsWith("chars:")) { // "chars:<chars> String chars = Regex.Unescape(cmd.Substring(6, cmd.Length - 6)); MainWindow.AddLogEntry(String.Format("Cmd: Sending {0} chars: {1}", chars.Length, chars)); var sim = new InputSimulator(); sim.Keyboard.TextEntry(chars); return; } if (cmd.StartsWith("api:")) { // "api:API(params) // TODO: Implement API stuff return; } if (cmd.StartsWith("shiftdown:")) { // Modifyer key down SendInputCommand.ShiftKey(cmd.Substring(10, cmd.Length - 10), true); return; } if (cmd.StartsWith("shiftup:")) { // Modifyer key up SendInputCommand.ShiftKey(cmd.Substring(8, cmd.Length - 8), false); return; } if (cmd.StartsWith(MouseCommand.CmdPrefix)) { // mouse:<action>[,<parameter>,<parameter>] var mouseCmd = new MouseCommand(cmd); mouseCmd.Execute(reply); return; } if (cmd.Length == 1) { // It's a single character, just send it // must be upper case (VirtualKeyCode codes are for upper case) cmd = cmd.ToUpper(); char c = cmd.ToCharArray()[0]; var sim = new InputSimulator(); MainWindow.AddLogEntry("Cmd: Sending keydown for: " + cmd); sim.Keyboard.KeyPress((VirtualKeyCode)c); return; } } // Command is in MCEControl.commands if (_hashTable.ContainsKey(cmd.ToUpper())) { Command command = FindKey(cmd.ToUpper()); command.Execute(reply); } else { MainWindow.AddLogEntry("Cmd: Unknown Cmd: " + cmd); } }
public static CommandTable Deserialize(bool DisableInternalCommands) { CommandTable cmds = null; CommandTable userCmds = null; if (!DisableInternalCommands) { // Load the built-in commands from an assembly resource try { var serializer = new XmlSerializer(typeof(CommandTable)); XmlReader reader = new XmlTextReader( Assembly.GetExecutingAssembly() .GetManifestResourceStream("MCEControl.Resources.MCEControl.commands")); cmds = (CommandTable)serializer.Deserialize(reader); foreach (var cmd in cmds.List) { if (cmds._hashTable.ContainsKey(cmd.Key.ToUpper())) { cmds._hashTable.Remove(cmd.Key.ToUpper()); } cmds._hashTable.Add(cmd.Key.ToUpper(), cmd); } } catch (Exception ex) { MessageBox.Show(String.Format("No commands loaded. Error parsing built-in commands. {0}", ex.Message)); MainWindow.AddLogEntry( String.Format("MCEC: No commands loaded. Error parsing built-in commands. {0}", ex.Message)); Util.DumpException(ex); return(null); } // Populate default VK_ codes foreach (VirtualKeyCode vk in Enum.GetValues(typeof(VirtualKeyCode))) { string s; if (vk > VirtualKeyCode.HELP && vk < VirtualKeyCode.LWIN) { s = vk.ToString(); // already have VK_ } else { s = "VK_" + vk.ToString(); } var cmd = new SendInputCommand(s, false, false, false, false); if (!cmds._hashTable.ContainsKey(s)) { cmds._hashTable.Add(s, cmd); } } } else { cmds = new CommandTable(); } // Load any over-rides from a text file FileStream fs = null; try { var serializer = new XmlSerializer(typeof(CommandTable)); // A FileStream is needed to read the XML document. fs = new FileStream("MCEControl.commands", FileMode.Open, FileAccess.Read); XmlReader reader = new XmlTextReader(fs); userCmds = (CommandTable)serializer.Deserialize(reader); foreach (var cmd in userCmds.List) { if (cmds._hashTable.ContainsKey(cmd.Key.ToUpper())) { cmds._hashTable.Remove(cmd.Key.ToUpper()); } cmds._hashTable.Add(cmd.Key.ToUpper(), cmd); } MainWindow.AddLogEntry(String.Format("MCEC: User defined commands loaded.")); } catch (FileNotFoundException ex) { MainWindow.AddLogEntry("MCEC: No user defined commands loaded; MCEControl.commands was not found."); Util.DumpException(ex); } catch (InvalidOperationException ex) { MainWindow.AddLogEntry( String.Format("MCEC: No commands loaded. Error parsing MCEControl.commands file. {0} {1}", ex.Message, ex.InnerException.Message)); Util.DumpException(ex); } catch (Exception ex) { MessageBox.Show(String.Format("No commands loaded. Error parsing MCEControl.commands file. {0}", ex.Message)); MainWindow.AddLogEntry(String.Format("MCEC: No commands loaded. Error parsing MCEControl.commands file. {0}", ex.Message)); Util.DumpException(ex); } finally { if (fs != null) { fs.Close(); } } return(cmds); }