PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Overthere/Interfaces/CmdConsole.cs

https://bitbucket.org/floAr/personal
C# | 195 lines | 158 code | 35 blank | 2 comment | 23 complexity | a04f6c2d3f3d701db014e94107e14993 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using Overthere.Interfaces;
  8. using System.Windows.Input;
  9. using System.Runtime.InteropServices;
  10. namespace Overthere
  11. {
  12. public class CmdConsole : IConsole, IDisposable
  13. {
  14. const int bufferSize = 5000;
  15. Process _cmdProcess;
  16. StreamWriter _inputStream;
  17. StreamReader _outputStream;
  18. StreamReader _errorStream;
  19. public CmdConsole()
  20. {
  21. string windowsDir = Environment.GetEnvironmentVariable("SystemRoot");
  22. string path = Path.Combine(windowsDir, "SysWOW64\\cmd.exe");
  23. if (!File.Exists(path))
  24. {
  25. path = Environment.GetEnvironmentVariable("ComSpec");
  26. }
  27. _cmdProcess = new Process();
  28. _cmdProcess.StartInfo.FileName = path;
  29. _cmdProcess.StartInfo.Arguments = "/K prompt $P$S$Q$G$S";
  30. _cmdProcess.StartInfo.CreateNoWindow = true;
  31. _cmdProcess.StartInfo.UseShellExecute = false;
  32. _cmdProcess.StartInfo.RedirectStandardOutput = true;
  33. _cmdProcess.StartInfo.RedirectStandardError = true;
  34. _cmdProcess.StartInfo.RedirectStandardInput = true;
  35. _cmdProcess.StartInfo.EnvironmentVariables["OTTEMP"] = Environment.GetEnvironmentVariable("TEMP");
  36. _cmdProcess.Start();
  37. _inputStream = _cmdProcess.StandardInput;
  38. _outputStream = _cmdProcess.StandardOutput;
  39. _errorStream = _cmdProcess.StandardError;
  40. byte[] outputBuffer = new byte[bufferSize];
  41. _outputStream.BaseStream.BeginRead(outputBuffer, 0, bufferSize, (ar) => DataReceived(ar, _outputStream.BaseStream, false), outputBuffer);
  42. byte[] errorBuffer = new byte[bufferSize];
  43. _errorStream.BaseStream.BeginRead(errorBuffer, 0, bufferSize, (ar) => DataReceived(ar, _errorStream.BaseStream, true), errorBuffer);
  44. }
  45. public void Dispose()
  46. {
  47. if (_cmdProcess != null)
  48. {
  49. _cmdProcess.Dispose();
  50. _cmdProcess = null;
  51. GC.SuppressFinalize(this);
  52. }
  53. }
  54. bool ignoreOutput = false;
  55. void DataReceived(IAsyncResult asyncResult, Stream stream, bool error)
  56. {
  57. int readCount = stream.EndRead(asyncResult);
  58. byte[] buffer = (byte[])asyncResult.AsyncState;
  59. if (readCount > 0 && !ignoreOutput)
  60. {
  61. string result = ASCIIEncoding.ASCII.GetString(buffer, 0, readCount);
  62. if (!error && Output != null)
  63. {
  64. Output(result);
  65. }
  66. else if (error && Error != null)
  67. {
  68. Error(result);
  69. }
  70. }
  71. stream.BeginRead(buffer, 0, buffer.Length, (ar) => DataReceived(ar, stream, error), buffer);
  72. }
  73. public void Input(string command)
  74. {
  75. _inputStream.Write(command);
  76. }
  77. public void InputCommand(string command)
  78. {
  79. Input(command + Environment.NewLine);
  80. }
  81. public event Action<string> Output;
  82. public event Action<string> Error;
  83. public string GetCurrentDirectory()
  84. {
  85. string path = Environment.GetEnvironmentVariable("TEMP") + "\\cd.txt";
  86. File.Delete(path);
  87. try
  88. {
  89. ignoreOutput = true;
  90. InputCommand("@echo off");
  91. InputCommand("cd > %OTTEMP%\\cd.txt");
  92. InputCommand("@echo on");
  93. for (int i = 0; i < 5; i++)
  94. {
  95. if (File.Exists(path))
  96. {
  97. try
  98. {
  99. string result = File.ReadAllText(path).Trim();
  100. File.Delete(path);
  101. return result;
  102. }
  103. catch (IOException)
  104. { }
  105. }
  106. System.Threading.Thread.Sleep(50);
  107. }
  108. return string.Empty;
  109. }
  110. finally
  111. {
  112. ignoreOutput = false;
  113. }
  114. }
  115. public IEnumerable<DirectoryInfo> GetDirectories(string directory)
  116. {
  117. try
  118. {
  119. DirectoryInfo dir = new DirectoryInfo(directory);
  120. return dir.GetDirectories().Where(d => (d.Attributes & FileAttributes.ReparsePoint) == 0).ToList();
  121. }
  122. catch
  123. {
  124. return new List<DirectoryInfo>();
  125. }
  126. }
  127. public IEnumerable<FileInfo> GetFiles(string directory)
  128. {
  129. try
  130. {
  131. DirectoryInfo dir = new DirectoryInfo(directory);
  132. return dir.GetFiles().Where(d => (d.Attributes & FileAttributes.ReparsePoint) == 0).ToList();
  133. }
  134. catch
  135. {
  136. return new List<FileInfo>();
  137. }
  138. }
  139. public void SendKey(Key key, ModifierKeys modifiers)
  140. {
  141. // Voodoo magic required to get the Ctrl+C/Break
  142. // to the cmdProcess without killing ourselves
  143. if ((key == Key.C || key == Key.Cancel) && KeyboardEx.IsControlDown)
  144. {
  145. UInt32 eventArg = key == Key.C ? CTRL_C_EVENT : CTRL_BREAK_EVENT;
  146. if (File.Exists("CtrlC.exe"))
  147. {
  148. Process process = new Process();
  149. process.StartInfo.FileName = "CtrlC.exe";
  150. process.StartInfo.Arguments = string.Format("{0} {1}", _cmdProcess.Id, eventArg);
  151. process.StartInfo.CreateNoWindow = true;
  152. process.StartInfo.UseShellExecute = false;
  153. process.Start();
  154. }
  155. }
  156. }
  157. public const UInt32 CTRL_C_EVENT = 0;
  158. public const UInt32 CTRL_BREAK_EVENT = 1;
  159. }
  160. }