WindowsConsoleDriver.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using BepInEx.ConsoleUtil;
  5. using UnityInjector.ConsoleUtil;
  6. namespace BepInEx
  7. {
  8. internal class WindowsConsoleDriver : IConsoleDriver
  9. {
  10. public TextWriter StandardOut { get; private set; }
  11. public TextWriter ConsoleOut { get; private set; }
  12. public bool ConsoleActive { get; private set; }
  13. public bool ConsoleIsExternal => true;
  14. public void Initialize(bool alreadyActive)
  15. {
  16. ConsoleActive = alreadyActive;
  17. StandardOut = Console.Out;
  18. }
  19. public void CreateConsole(uint codepage)
  20. {
  21. // On some Unity mono builds the SafeFileHandle overload for FileStream is missing
  22. // so we use the older but always included one instead
  23. #pragma warning disable 618
  24. ConsoleWindow.Attach();
  25. // Make sure of ConsoleEncoding helper class because on some Monos
  26. // Encoding.GetEncoding throws NotImplementedException on most codepages
  27. // NOTE: We don't set Console.OutputEncoding because it resets any existing Console.Out writers
  28. ConsoleEncoding.ConsoleCodePage = codepage;
  29. // If stdout exists, write to it, otherwise make it the same as console out
  30. // Not sure if this is needed? Does the original Console.Out still work?
  31. var stdout = GetOutHandle();
  32. if (stdout == IntPtr.Zero)
  33. {
  34. StandardOut = TextWriter.Null;
  35. ConsoleOut = TextWriter.Null;
  36. return;
  37. }
  38. var originalOutStream = new FileStream(stdout, FileAccess.Write);
  39. StandardOut = new StreamWriter(originalOutStream, new UTF8Encoding(false))
  40. {
  41. AutoFlush = true
  42. };
  43. var consoleOutStream = new FileStream(ConsoleWindow.ConsoleOutHandle, FileAccess.Write);
  44. // Can't use Console.OutputEncoding because it can be null (i.e. not preference by user)
  45. ConsoleOut = new StreamWriter(consoleOutStream, ConsoleEncoding.OutputEncoding)
  46. {
  47. AutoFlush = true
  48. };
  49. ConsoleActive = true;
  50. #pragma warning restore 618
  51. }
  52. private IntPtr GetOutHandle()
  53. {
  54. switch (ConsoleManager.ConfigConsoleOutRedirectType.Value)
  55. {
  56. case ConsoleManager.ConsoleOutRedirectType.ConsoleOut:
  57. return ConsoleWindow.ConsoleOutHandle;
  58. case ConsoleManager.ConsoleOutRedirectType.StandardOut:
  59. return ConsoleWindow.OriginalStdoutHandle;
  60. case ConsoleManager.ConsoleOutRedirectType.Auto:
  61. default:
  62. return ConsoleWindow.OriginalStdoutHandle != IntPtr.Zero ? ConsoleWindow.OriginalStdoutHandle : ConsoleWindow.ConsoleOutHandle;
  63. }
  64. }
  65. public void DetachConsole()
  66. {
  67. ConsoleWindow.Detach();
  68. ConsoleOut.Close();
  69. ConsoleOut = null;
  70. ConsoleActive = false;
  71. }
  72. public void SetConsoleColor(ConsoleColor color)
  73. {
  74. SafeConsole.ForegroundColor = color;
  75. Kon.ForegroundColor = color;
  76. }
  77. public void SetConsoleTitle(string title)
  78. {
  79. ConsoleWindow.Title = title;
  80. }
  81. }
  82. }