ConsoleHelp.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #region << 版本注释-v2 >>
  2. /*
  3. * ========================================================================
  4. * 版本:v2
  5. * 时间:2021-09-03
  6. * 作者:lith
  7. * 邮箱:serset@yeah.net
  8. * 说明:
  9. * ========================================================================
  10. */
  11. #endregion
  12. using System;
  13. using System.Linq;
  14. using System.Reflection;
  15. namespace Vit.ConsoleUtil
  16. {
  17. #region ConsoleHelp
  18. public class ConsoleHelp
  19. {
  20. public static Action<string> Log = (msg) => { Console.WriteLine(msg); };
  21. public static Action<string> Out = (msg) => { Console.WriteLine(msg); };
  22. #region GetArg
  23. /// <summary>
  24. /// null: 未指定参数
  25. /// "" : 指定了参数,但未指定值
  26. /// 其他: 指定了参数,其为参数的值
  27. /// </summary>
  28. /// <param name="args"> </param>
  29. /// <param name="argName">参数名 如 "-createTable"</param>
  30. /// <returns></returns>
  31. public static string GetArg(string[] args, string argName)
  32. {
  33. var index = Array.IndexOf(args, argName);
  34. if (index < 0) return null;
  35. if (index + 1 == args.Length)
  36. {
  37. return "";
  38. }
  39. var value = args[index + 1];
  40. if (value.StartsWith('-')) return "";
  41. return value;
  42. }
  43. #endregion
  44. #region Exec
  45. /// <summary>
  46. /// 查找CommandAttribute特性的静态函数并按参数指定调用
  47. /// </summary>
  48. /// <param name="args"></param>
  49. public static void Exec(string[] args)
  50. {
  51. //var arg = new List<string>() { "un7z" };
  52. //arg.AddRange(new[] { "-i", "T:\\temp\\tileset.7z.001" });
  53. //arg.AddRange(new[] { "-o", "T:\\temp\\un7z" });
  54. //args = arg.ToArray();
  55. #region (x.1)通过反射获取所有命令
  56. var cmdMap =
  57. //获取所有type
  58. Assembly.GetEntryAssembly().GetTypes()
  59. //获取所有静态函数
  60. .SelectMany(type => type.GetMethods(BindingFlags.Static | BindingFlags.Public))
  61. //获取指定CommandAttribute的函数
  62. .Where(m => m.GetCustomAttribute<CommandAttribute>() != null)
  63. //按照 命令名称 和 Method 构建Dictionary
  64. .ToDictionary(
  65. m => (m.GetCustomAttribute<CommandAttribute>().Value ?? m.Name)
  66. , m => m
  67. );
  68. #endregion
  69. #region (x.2)若未指定命令名称,则输出帮助文档
  70. if (args == null || args.Length == 0 || string.IsNullOrEmpty(args[0]))
  71. {
  72. #region 输出命令帮助文档
  73. ConsoleHelp.Log("命令帮助文档:");
  74. foreach (var cmd in cmdMap)
  75. {
  76. ConsoleHelp.Log("---------------");
  77. ConsoleHelp.Log(cmd.Key);
  78. cmd.Value.GetCustomAttributes<RemarksAttribute>()?.Select(m => m.Value).ToList().ForEach(ConsoleHelp.Log);
  79. }
  80. ConsoleHelp.Log("---------------");
  81. ConsoleHelp.Log("");
  82. ConsoleHelp.Log("");
  83. #endregion
  84. return;
  85. }
  86. #endregion
  87. #region (x.3)通过第一个参数查找命令并调用
  88. try
  89. {
  90. cmdMap.TryGetValue(args[0], out var method);
  91. if (method == null)
  92. {
  93. throw new Exception($"命令 { args[0] } 不存在!(help命令可查看命令说明)");
  94. }
  95. ConsoleHelp.Log("------------------------------");
  96. ConsoleHelp.Log($"开始执行命令 { args[0] } ...");
  97. ConsoleHelp.Log("---------------");
  98. method.Invoke(null, new object[] { args });
  99. }
  100. catch (Exception ex)
  101. {
  102. ex = ex.GetBaseException();
  103. ConsoleHelp.Log("出错:" + ex.Message);
  104. ConsoleHelp.Log("出错:" + ex.StackTrace);
  105. exitCode = 1;
  106. }
  107. #endregion
  108. ConsoleHelp.Log("结束!!");
  109. Exit();
  110. return;
  111. }
  112. #endregion
  113. #region Exit
  114. public static int exitCode = 0;
  115. public static void Exit()
  116. {
  117. //退出当前进程以及当前进程开启的所有进程
  118. System.Environment.Exit(exitCode);
  119. }
  120. #endregion
  121. #region command help
  122. [Command("help")]
  123. [Remarks("命令说明:")]
  124. [Remarks("-c[--command] 要查询的命令。若不指定则返回所有命令的说明。如 help ")]
  125. [Remarks("示例: help -c help")]
  126. public static void Help(string[] args)
  127. {
  128. string cmdName = ConsoleHelp.GetArg(args, "-c") ?? ConsoleHelp.GetArg(args, "--command");
  129. #region (x.1)通过反射获取所有命令
  130. var cmdMap =
  131. //获取所有type
  132. Assembly.GetEntryAssembly().GetTypes()
  133. //获取所有静态函数
  134. .SelectMany(type => type.GetMethods(BindingFlags.Static | BindingFlags.Public))
  135. //获取指定CommandAttribute的函数
  136. .Where(m => m.GetCustomAttribute<CommandAttribute>() != null)
  137. //按照 命令名称 和 Method 构建Dictionary
  138. .ToDictionary(
  139. m => (m.GetCustomAttribute<CommandAttribute>().Value ?? m.Name)
  140. , m => m
  141. );
  142. #endregion
  143. #region (x.2)筛选指定命令
  144. if (!string.IsNullOrEmpty(cmdName))
  145. {
  146. cmdMap.TryGetValue(cmdName, out var cmdMethod);
  147. cmdMap = new System.Collections.Generic.Dictionary<string, MethodInfo>();
  148. if (cmdMethod != null)
  149. {
  150. cmdMap[cmdName] = cmdMethod;
  151. }
  152. }
  153. #endregion
  154. #region (x.3)输出命令说明:
  155. ConsoleHelp.Log("命令说明:");
  156. foreach (var cmd in cmdMap)
  157. {
  158. ConsoleHelp.Log("---------------");
  159. ConsoleHelp.Log(cmd.Key);
  160. cmd.Value.GetCustomAttributes<RemarksAttribute>()?.Select(m => m.Value).ToList().ForEach(ConsoleHelp.Log);
  161. }
  162. ConsoleHelp.Log("---------------");
  163. ConsoleHelp.Log("");
  164. ConsoleHelp.Log("");
  165. #endregion
  166. }
  167. #endregion
  168. }
  169. #endregion
  170. }