/// <summary> /// Executes this command with the given arguments. /// </summary> /// <param name="args"></param> /// <returns></returns> public int ExecuteCommand(CommandLineInfo info, ParameterInfo args) { if (IsInternal) { if (Handler == null) { return(-1); } else { return(Handler(info, args)); } } return(-1); }
/// <summary> /// Change the directory. /// </summary> /// <param name="info"></param> /// <returns></returns> public static int ChangeDir(CommandLineInfo info, ParameterInfo args) { string dir = ""; if (args.ArgumentValues.ContainsKey("directory")) { dir = args.ArgumentValues["directory"].Trim(); } if (dir != "") { if (Directory.Exists(Path.GetFullPath(dir))) { Directory.SetCurrentDirectory(Path.GetFullPath(dir)); } else { Console.WriteLine("Directory does not exist."); } } else if (args.GenericArgs.Count > 0) { dir = args.GenericArgs[0].Trim(); if (dir != "") { if (Directory.Exists(Path.GetFullPath(dir))) { Directory.SetCurrentDirectory(Path.GetFullPath(dir)); } else { Console.WriteLine("Directory does not exist."); } } } else { Console.WriteLine("Invalid command usage. Try help --command cd"); } args.ArgumentValues.Clear(); args.GenericArgs.Clear(); return(0); }
static void Main(string[] args) { List <string> commandArgs = new List <string>(); DisplayLogo(); ShellConsole console = new ShellConsole(); console.RegisterCommand(new string[] { "cd" }, new ParamPair[] { new ParamPair("d", "directory") }, CommonCommands.ChangeDir ); while (true) { console.DisplayPrompt(); string str = console.ReadCommandLine(); CommandLineInfo info = console.ParseCommandLine(str, ref commandArgs); console.HandleCommand(info); } }
/// <summary> /// Handles a command by executing it with the given arguments. /// </summary> /// <param name="commandName">The name of the command to execute</param> /// <param name="args">The list of arguments to pass to the command</param> /// <returns>The integer result of the command.</returns> public int HandleCommand(CommandLineInfo info) { if (info == null) { return(-1); } // First we need to find the command to actually execute. string commandToFind = info.CommandName; ParameterInfo paramInfo = new ParameterInfo(); // First let's check if it is a predefined/loaded command. foreach (CommandInfo command in Commands) { if (command.IsCommandName(commandToFind)) { paramInfo = command.ParameterInfo; // we need to parse out the list of arguments based on long-name/short-name for (int i = 0; i < info.Arguments.Count; i++) { if (info.Arguments[i].StartsWith("--") && (i < info.Arguments.Count - 1)) { // it's already a long-name string realArgName = info.Arguments[i].Substring(2); string realArgValue = info.Arguments[i + 1]; i++; paramInfo.ArgumentValues[realArgName] = realArgValue; } else if (info.Arguments[i].StartsWith("-") && (i < info.Arguments.Count - 1)) { string realArgName = info.Arguments[i].Substring(1); string realArgValue = info.Arguments[i + 1]; i++; paramInfo.ArgumentValues[paramInfo.ParameterNames[realArgName]] = realArgValue; } else { paramInfo.GenericArgs.Add(info.Arguments[i]); } } return(command.ExecuteCommand(info, paramInfo)); } } // It wasn't a predefined command, let's check to see if it is a file path string fullPathTest = Path.GetFullPath(commandToFind); if (fullPathTest.IndexOfAny(Path.GetInvalidPathChars()) == -1) { if (Directory.Exists(fullPathTest)) { Console.WriteLine(fullPathTest + " is a directory."); return(0); } } if (File.Exists(fullPathTest)) { ProcessStartInfo procInfo = new ProcessStartInfo(fullPathTest, info.RawArgumentLine); procInfo.RedirectStandardError = true; procInfo.RedirectStandardInput = true; procInfo.RedirectStandardOutput = true; procInfo.WorkingDirectory = Path.GetFullPath(Directory.GetCurrentDirectory()); procInfo.UseShellExecute = false; procInfo.WindowStyle = ProcessWindowStyle.Hidden; procInfo.CreateNoWindow = true; Process proc = new Process(); proc.StartInfo = procInfo; //proc.OutputDataReceived += (s, e) => { Console.Write(e.Data); proc.StandardInput.Flush(); }; //proc.ErrorDataReceived += (s, e) => { Console.Write(e.Data); proc.StandardInput.Flush(); }; proc.Start(); //Stream stream = Console.OpenStandardInput(); bool isReading = false; Thread readerThread = new Thread(() => { while (true) { int res = proc.StandardOutput.BaseStream.ReadByte(); if (res > -1) { Console.Write((char)res); isReading = true; } else { isReading = false; } } }); Thread errorThread = new Thread(() => { while (true) { if (!isReading) { proc.StandardError.BaseStream.Flush(); int res = proc.StandardError.BaseStream.ReadByte(); if (res > -1) { Console.Write((char)res); } } } }); readerThread.Start(); errorThread.Start(); while (!proc.HasExited) { proc.StandardInput.Write((char)Console.Read()); } readerThread.Abort(); errorThread.Abort(); // redisplay our prompt! Console.WriteLine(""); Console.Out.Flush(); DisplayPrompt(); } return(-1); }
/// <summary> /// Parses a read command-line. /// </summary> /// <param name="commandLine">The command-line to parse</param> /// <param name="args">The arguments that were parsed from the command-line</param> /// <returns>The name of the command</returns> public CommandLineInfo ParseCommandLine(string commandLine, ref List <string> args) { CommandLineInfo info = new CommandLineInfo(); info.RawCommandLine = commandLine; commandLine = commandLine.Trim(); if (commandLine.Length <= 0) { return(null); } // create our argument list args = new List <string>(); string commandPart = ""; //string tempArgPart = ""; int strLen = commandLine.Length; //int startSub = 0; //int endSub = 0; int i = 0; // first we are looking for the command-name. for (i = 0; i < strLen; i++) { if (commandLine[i] == ' ') { break; } } commandPart = commandLine.Substring(0, i); info.CommandName = commandPart; string argString = commandLine.Substring(i).Trim(); info.RawArgumentLine = argString; strLen = argString.Length; bool inQuotes = false; int lastStartIndex = 0; for (i = 0; i < strLen; i++) { if (argString[i] == '"') { if (inQuotes) { string singleArgStr = argString.Substring(lastStartIndex + 1, i - (lastStartIndex + 1)); lastStartIndex = i + 1; inQuotes = false; args.Add(singleArgStr); } else { inQuotes = true; lastStartIndex = i; } } else if (Char.IsWhiteSpace(argString[i]) && !inQuotes) { if (i - lastStartIndex <= 0) { continue; } string singleArgStr = argString.Substring(lastStartIndex, i - (lastStartIndex)); lastStartIndex = i + 1; args.Add(singleArgStr); } } if (i - lastStartIndex > 0) { string singleArgStr = argString.Substring(lastStartIndex, i - (lastStartIndex)); args.Add(singleArgStr); } foreach (string s in args) { info.Arguments.Add(s); } return(info); }
/// <summary> /// Lists all files and directories in the current working directory. /// If no argument is given, lists files in the current directory. /// Otherwise, in the specified directory. /// Alias: ls, dir /// </summary> /// <param name="info"></param> /// <returns></returns> static public int ListFiles(CommandLineInfo info, ParameterInfo args) { return(0); }
/// <summary> /// Clears the screen. /// Alias: clear, cls /// </summary> /// <param name="info"></param> /// <returns></returns> static public int ClearConsole(CommandLineInfo info, ParameterInfo args) { Console.Clear(); return(0); }