private Task ProcessWithHelp(IInput input, IHostContext context, ICommandProvider commandProvider) { string helpCommand = null; if (input.Options.TryGetValue("command", out object commandOption)) { if (commandOption is string) { helpCommand = (string)commandOption; } else if (commandOption is IEnumerable <string> commandEnum) { helpCommand = commandEnum.FirstOrDefault(); } } if (helpCommand == null) { foreach (object arg in input.Arguments) { if (arg is string) { helpCommand = (string)arg; break; } else if (arg is IEnumerable <string> argEnum) { helpCommand = argEnum.FirstOrDefault(); if (helpCommand != null) { break; } } } } if (helpCommand == null) { context.SetResult(GetCommandsList(commandProvider)); } else { CommandRecord commandRecord = commandProvider.MatchCommandByName(helpCommand); if (commandRecord == null) { Exception error = new Exception($"command not found: {helpCommand}"); context.Exception = error; } else { string commandName = commandRecord.Command; MethodInfo entryMethod = commandRecord.CommandEntry; context.SetResult(CommandInfo.GetInfo(commandName, entryMethod)); } } return(Task.CompletedTask); }
public Task Invoke(IHostContext context, Func <Task> next, IServiceProvider services, ICommandProvider commandProvider, IEnvironment env, IOutputEngine outputEngine, IHostInput hostInput) { IInput input = context.Command; if (input.Name == "help") { return(ProcessWithHelp(input, context, commandProvider)); } CommandRecord command = commandProvider.MatchCommand(context); if (command == null) { return(next()); } MethodInfo methodInfo = command.CommandEntry; ParameterInfo[] parameters = methodInfo.GetParameters(); List <int> pathIndices = new List <int>(); foreach (var parameter in parameters) { if (parameter.GetCustomAttribute <PathAttribute>() != null) { pathIndices.Add(parameter.Position); } } try { CommandSet instance = (CommandSet)ObjectFactory.CreateInstance(command.InstanceType, services, input.Options, input.Arguments); instance.Command = input; instance.Context = context; instance.InputObject = context.InputObject; instance.OutputEngine = outputEngine; instance.HostInput = hostInput; instance.Environment = env; object value; if (pathIndices.Count <= 0) { value = ObjectFactory.InvokeMethod(instance, methodInfo, services, input.Options, input.Arguments); } else { MethodInvokeContext invokeContext = ObjectFactory.CreateInvokeContext(methodInfo, services, input.Options, input.Arguments); string currentPath = env.WorkingDirectory.FullName; ProcessPathAttribute(pathIndices, parameters, invokeContext.Arguments, currentPath); value = invokeContext.Invoke(instance); } if (command.CommandEntry.ReturnType != typeof(void)) { context.SetResult(value); } } catch (Exception ex) { context.Exception = ex; } return(Task.CompletedTask); }
private Dictionary <string, CommandRecord> LoadCommands() { Dictionary <string, CommandRecord> commands = new Dictionary <string, CommandRecord>(); string dir = new FileInfo(Assembly.GetEntryAssembly().Location).Directory.FullName; DirectoryInfo directoryInfo = new DirectoryInfo(dir); FileInfo[] files = directoryInfo.GetFiles("*.dll"); Type commandsetType = typeof(CommandSet); string typeName; string methodName; string command; IEnumerable <CommandAttribute> commandAttributes; foreach (FileInfo file in files) { Assembly assembly = Assembly.Load(AssemblyLoadContext.GetAssemblyName(file.FullName)); Type[] types = assembly.GetTypes(); foreach (Type type in types) { TypeInfo typeInfo = type.GetTypeInfo(); if (typeInfo.IsArray == true) { continue; } if (typeInfo.IsEnum == true) { continue; } if (typeInfo.IsAbstract == true) { continue; } if (typeInfo.IsInterface == true) { continue; } if (typeInfo.IsClass == false) { continue; } if (!commandsetType.IsAssignableFrom(type)) { continue; } typeName = type.Name; if (typeName.EndsWith("Commands")) { typeName = typeName.Substring(0, typeName.Length - 8); } typeName = typeName.ToLower(); foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { methodName = method.Name.ToLower(); commandAttributes = method.GetCustomAttributes <CommandAttribute>(); foreach (CommandAttribute commandAttribute in commandAttributes) { command = commandAttribute.Name.Trim().ToLower(); if (command.Length <= 0) { continue; } commands[command] = new CommandRecord(command, type, method); } } } } return(commands); }