internal CommandLineInfoHandler(object commandlineinfo) { Type infoType = commandlineinfo.GetType(); SortedList <int, MemberInfo> argumentHandlers = new SortedList <int, MemberInfo>(); foreach (MemberInfo member in infoType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty)) { // Retrieve help options: CommandHelpAttribute helpattr = CommandHelpAttribute.Get(member); if (helpattr != null) { this.HelpOptions.AddRange(helpattr.HelpOptions); this.HelpHandler = member; continue; // Skip testing other types of handlers } // Retrieve argument handlers: CommandArgAttribute argattr = CommandArgAttribute.Get(member); if (argattr != null) { argumentHandlers.Add(argattr.Order, member); if (argattr.IsRequired) { this.NumberOfRequiredArgs++; } continue; // Skip testing other types of handlers } // Retrieve argumentlist handler: CommandArgListAttribute arglistattr = CommandArgListAttribute.Get(member); if (arglistattr != null) { this.ArgumentListHandler = member; // Initialize the member to empty list: if (member is FieldInfo) { ((FieldInfo)member).SetValue(commandlineinfo, new List <string>()); } else // Assume PropertyInfo { ((PropertyInfo)member).SetValue(commandlineinfo, new List <string>(), null); } if (arglistattr.IsRequired) { this.NumberOfRequiredArgs++; } continue; // Skip testing other types of handlers } // Retrieve option handlers: CommandOptionAttribute optattr = CommandOptionAttribute.Get(member); if (optattr != null) { // Option values: Dictionary <string, object> values = new Dictionary <string, object>(); // Register name, and eventual shortname: this.OptionHandlers.Add(optattr.Name, member); this.OptionValues.Add(optattr.Name, values); if (optattr.ShortName != null) { this.OptionHandlers.Add(optattr.ShortName, member); this.OptionValues.Add(optattr.ShortName, values); } // If not required, then default value is provided: if (optattr.IsRequired == false) { // Set default value: if (member is FieldInfo) { ((FieldInfo)member).SetValue(commandlineinfo, optattr.DefaultValue); } else if (member is PropertyInfo) { ((PropertyInfo)member).SetValue(commandlineinfo, optattr.DefaultValue, null); } } // Retrieve optionValues: CommandOptionValueAttribute[] optvalattrs = CommandOptionAttribute.GetValues(member); foreach (CommandOptionValueAttribute valattr in optvalattrs) { values.Add(valattr.UserValue, valattr.Value); } } } this.ArgumentHandlers = argumentHandlers.Values; }
/// <summary> /// Generate the parameter section of commandline help /// based on the given commandlineinfo type. /// The commandlineinfo type must have fields or properties /// decorated with CommandArg, CommandOption,... attributes. /// </summary> public string GenerateHelp(Type commandlineinfotype) { StringBuilder sb = new StringBuilder(); Assembly entryAssembly = Assembly.GetEntryAssembly(); MemberInfo help = null; SortedList <int, MemberInfo> args = new SortedList <int, MemberInfo>(); MemberInfo argList = null; List <MemberInfo> options = new List <MemberInfo>(); // Retrieve members: foreach (MemberInfo member in commandlineinfotype.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty)) { if (CommandArgAttribute.Get(member) != null) { args.Add(CommandArgAttribute.Get(member).Order, member); } else if (CommandArgListAttribute.Get(member) != null) { argList = member; } else if (CommandOptionAttribute.Get(member) != null) { options.Add(member); } else if (CommandHelpAttribute.Get(member) != null) { help = member; } } // Write application title: sb.AppendLine(((AssemblyTitleAttribute)entryAssembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false)[0]).Title); sb.AppendLine(); // Write application description: if (commandlineinfotype.GetCustomAttributes(typeof(CommandInfoAttribute), false).Length > 0) { // Based on CommandInfoAttribute if available: sb.AppendLine(((CommandInfoAttribute)commandlineinfotype.GetCustomAttributes(typeof(CommandInfoAttribute), false)[0]).Description); sb.AppendLine(); } else { // Else based on AssemblyDescriptionAttribute: var descattr = ((AssemblyDescriptionAttribute)entryAssembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false)[0]); if ((descattr != null) && (!String.IsNullOrWhiteSpace(descattr.Description))) { sb.AppendLine(descattr.Description); sb.AppendLine(); } } // Write syntax: sb.AppendLine("Syntax:"); sb.Append(" {command}"); foreach (MemberInfo argMember in args.Values) { CommandArgAttribute argDef = CommandArgAttribute.Get(argMember); sb.Append(' '); sb.Append((argDef.IsRequired) ? '<' : '['); sb.Append(argDef.Name); sb.Append((argDef.IsRequired) ? '>' : ']'); } if (argList != null) { CommandArgListAttribute arglDef = CommandArgListAttribute.Get(argList); sb.Append(' '); sb.Append((arglDef.IsRequired) ? '<' : '['); sb.Append(arglDef.Name); sb.Append("..."); sb.Append((arglDef.IsRequired) ? '>' : ']'); } foreach (MemberInfo optMember in options) { CommandOptionAttribute optDef = CommandOptionAttribute.Get(optMember); Type optType = CommandOptionAttribute.GetValueType(optMember); CommandOptionValueAttribute[] optValues = CommandOptionAttribute.GetValues(optMember); sb.Append(' '); if (optDef.IsRequired == false) { sb.Append('['); } sb.Append(this.optionMarker); sb.Append(optDef.Name); if (optValues.Length > 0) { sb.Append(this.valueSeparator); string separator = ""; foreach (CommandOptionValueAttribute value in optValues) { sb.Append(separator); sb.Append(value.UserValue); separator = "|"; } } else if (optType.Equals(typeof(Boolean)) == false) { sb.Append(this.valueSeparator); sb.Append("?"); } if (optDef.IsRequired == false) { sb.Append(']'); } } sb.AppendLine(); sb.AppendLine(); // Write argument details: foreach (MemberInfo argMember in args.Values) { CommandArgAttribute argDef = CommandArgAttribute.Get(argMember); CommandInfoAttribute info = CommandInfoAttribute.Get(argMember); sb.Append(' '); sb.Append(String.Concat(argDef.Name, new String(' ', 13)).Substring(0, 13)); sb.Append(' '); if (info != null) { sb.Append(info.Description); } else { sb.Append(argDef.Name); } sb.AppendLine(); } if (argList != null) { CommandArgListAttribute arglDef = CommandArgListAttribute.Get(argList); CommandInfoAttribute info = CommandInfoAttribute.Get(argList); sb.Append(' '); sb.Append(String.Concat(arglDef.Name, new String(' ', 13)).Substring(0, 13)); sb.Append(' '); if (info != null) { sb.Append(info.Description); } else { sb.Append("..."); } sb.AppendLine(); } // Write option details: foreach (MemberInfo optMember in options) { CommandOptionAttribute optDef = CommandOptionAttribute.Get(optMember); CommandInfoAttribute info = CommandInfoAttribute.Get(optMember); Type optType = CommandOptionAttribute.GetValueType(optMember); CommandOptionValueAttribute[] optValues = CommandOptionAttribute.GetValues(optMember); string optname = this.optionMarker + optDef.Name; if (optDef.ShortName != null) { optname += "|" + optDef.ShortName; } sb.Append(' '); sb.Append(String.Concat(optname, new String(' ', 13)).Substring(0, 13)); sb.Append(' '); if (info != null) { sb.Append(info.Description); } else { sb.Append(optDef.Name); } if (optValues.Length > 0) { sb.Append(':'); } sb.AppendLine(); foreach (CommandOptionValueAttribute value in optValues) { sb.Append(" "); sb.Append(String.Concat(value.UserValue, new String(' ', 13)).Substring(0, 13)); sb.Append(' '); sb.Append(value.Description); sb.AppendLine(); } } sb.AppendLine(); // Write samples: if (commandlineinfotype.GetCustomAttributes(typeof(CommandExampleAttribute), false).Length > 0) { sb.AppendLine("Examples:"); CommandExampleAttribute[] samples = CommandExampleAttribute.GetValues(commandlineinfotype); for (int i = samples.Length - 1; i >= 0; i--) { CommandExampleAttribute sample = samples[i]; sb.Append(" {command} "); sb.AppendLine(sample.Sample); if (!String.IsNullOrEmpty(sample.Description)) { sb.Append(" "); sb.AppendLine(sample.Description); } } sb.AppendLine(); } // Write application copyright: if (AssemblyCopyrightAttribute.GetCustomAttribute(entryAssembly, typeof(AssemblyCopyrightAttribute)) != null) { sb.AppendLine(((AssemblyCopyrightAttribute)AssemblyCopyrightAttribute.GetCustomAttribute(entryAssembly, typeof(AssemblyCopyrightAttribute))).Copyright.Replace("©", "(C)")); sb.AppendLine(); } // Perform substitutions of variables: sb = sb.Replace("{command}", System.Diagnostics.Process.GetCurrentProcess().ProcessName); // Returns the whole help: return(sb.ToString()); }