ConsoleManager.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using System;
  2. using System.ComponentModel;
  3. using System.IO;
  4. using System.Text;
  5. using BepInEx.Configuration;
  6. using BepInEx.Unix;
  7. using MonoMod.Utils;
  8. namespace BepInEx
  9. {
  10. internal static class ConsoleManager
  11. {
  12. private const uint SHIFT_JIS_CP = 932;
  13. internal static IConsoleDriver Driver { get; set; }
  14. /// <summary>
  15. /// True if an external console has been started, false otherwise.
  16. /// </summary>
  17. public static bool ConsoleActive => Driver?.ConsoleActive ?? false;
  18. /// <summary>
  19. /// The stream that writes to the standard out stream of the process. Should never be null.
  20. /// </summary>
  21. public static TextWriter StandardOutStream => Driver?.StandardOut;
  22. /// <summary>
  23. /// The stream that writes to an external console. Null if no such console exists
  24. /// </summary>
  25. public static TextWriter ConsoleStream => Driver?.ConsoleOut;
  26. public static void Initialize(bool alreadyActive)
  27. {
  28. if (PlatformHelper.Is(Platform.Unix))
  29. {
  30. Driver = new LinuxConsoleDriver();
  31. }
  32. else if (PlatformHelper.Is(Platform.Windows))
  33. {
  34. Driver = new WindowsConsoleDriver();
  35. }
  36. Driver.Initialize(alreadyActive);
  37. }
  38. private static void DriverCheck()
  39. {
  40. if (Driver == null)
  41. throw new InvalidOperationException("Driver has not been initialized");
  42. }
  43. public static void CreateConsole()
  44. {
  45. if (ConsoleActive)
  46. return;
  47. DriverCheck();
  48. // Apparently some versions of Mono throw a "Encoding name 'xxx' not supported"
  49. // if you use Encoding.GetEncoding
  50. // That's why we use of codepages directly and handle then in console drivers separately
  51. var codepage = ConfigConsoleShiftJis.Value ? SHIFT_JIS_CP: (uint)Encoding.UTF8.CodePage;
  52. Driver.CreateConsole(codepage);
  53. }
  54. public static void DetachConsole()
  55. {
  56. if (!ConsoleActive)
  57. return;
  58. DriverCheck();
  59. Driver.DetachConsole();
  60. }
  61. public static void SetConsoleTitle(string title)
  62. {
  63. DriverCheck();
  64. Driver.SetConsoleTitle(title);
  65. }
  66. public static void SetConsoleColor(ConsoleColor color)
  67. {
  68. DriverCheck();
  69. Driver.SetConsoleColor(color);
  70. }
  71. public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.Bind(
  72. "Logging.Console", "Enabled",
  73. false,
  74. "Enables showing a console for log output.");
  75. public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.Bind(
  76. "Logging.Console", "ShiftJisEncoding",
  77. false,
  78. "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
  79. public static readonly ConfigEntry<ConsoleOutRedirectType> ConfigConsoleOutRedirectType = ConfigFile.CoreConfig.Bind(
  80. "Logging.Console", "StandardOutType",
  81. ConsoleOutRedirectType.Auto,
  82. new StringBuilder()
  83. .AppendLine("Hints console manager on what handle to assign as StandardOut. Possible values:")
  84. .AppendLine("Auto - lets BepInEx decide how to redirect console output")
  85. .AppendLine("ConsoleOut - prefer redirecting to console output; if possible, closes original standard output")
  86. .AppendLine("StandardOut - prefer redirecting to standard output; if possible, closes console out")
  87. .ToString()
  88. );
  89. public enum ConsoleOutRedirectType
  90. {
  91. [Description("Auto")] Auto = 0,
  92. [Description("Console Out")] ConsoleOut,
  93. [Description("Standard Out")] StandardOut,
  94. }
  95. }
  96. }