ConsoleWindow.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // --------------------------------------------------
  2. // UnityInjector - ConsoleWindow.cs
  3. // Copyright (c) Usagirei 2015 - 2015
  4. // --------------------------------------------------
  5. using System;
  6. using System.IO;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. namespace UnityInjector.ConsoleUtil
  10. {
  11. internal class ConsoleWindow
  12. {
  13. private static bool _attached;
  14. private static IntPtr _cOut;
  15. private static IntPtr _oOut;
  16. public static void Attach()
  17. {
  18. if (_attached)
  19. return;
  20. if (_oOut == IntPtr.Zero)
  21. _oOut = GetStdHandle(-11);
  22. // Store Current Window
  23. IntPtr currWnd = GetForegroundWindow();
  24. if (!AllocConsole())
  25. throw new Exception("AllocConsole() failed");
  26. // Restore Foreground
  27. SetForegroundWindow(currWnd);
  28. _cOut = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
  29. if (!SetStdHandle(-11, _cOut))
  30. throw new Exception("SetStdHandle() failed");
  31. Init();
  32. _attached = true;
  33. }
  34. public static void Detach()
  35. {
  36. if (!_attached)
  37. return;
  38. if (!CloseHandle(_cOut))
  39. throw new Exception("CloseHandle() failed");
  40. _cOut = IntPtr.Zero;
  41. if (!FreeConsole())
  42. throw new Exception("FreeConsole() failed");
  43. if (!SetStdHandle(-11, _oOut))
  44. throw new Exception("SetStdHandle() failed");
  45. Init();
  46. _attached = false;
  47. }
  48. [DllImport("user32.dll")]
  49. private static extern IntPtr GetForegroundWindow();
  50. [DllImport("user32.dll")]
  51. [return: MarshalAs(UnmanagedType.Bool)]
  52. static extern bool SetForegroundWindow(IntPtr hWnd);
  53. [DllImport("kernel32.dll", SetLastError = true)]
  54. private static extern bool AllocConsole();
  55. [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
  56. private static extern bool CloseHandle(IntPtr handle);
  57. [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  58. private static extern IntPtr CreateFile(
  59. string fileName,
  60. int desiredAccess,
  61. int shareMode,
  62. IntPtr securityAttributes,
  63. int creationDisposition,
  64. int flagsAndAttributes,
  65. IntPtr templateFile);
  66. [DllImport("kernel32.dll", SetLastError = false)]
  67. private static extern bool FreeConsole();
  68. [DllImport("kernel32.dll", SetLastError = true)]
  69. private static extern IntPtr GetStdHandle(int nStdHandle);
  70. private static void Init()
  71. {
  72. var stdOut = Console.OpenStandardOutput();
  73. var stdWriter = new StreamWriter(stdOut, Encoding.Default)
  74. {
  75. AutoFlush = true
  76. };
  77. Console.SetOut(stdWriter);
  78. Console.SetError(stdWriter);
  79. }
  80. [DllImport("kernel32.dll", SetLastError = true)]
  81. private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput);
  82. }
  83. }