/Overthere/Interfaces/CmdConsole.cs
C# | 195 lines | 158 code | 35 blank | 2 comment | 23 complexity | a04f6c2d3f3d701db014e94107e14993 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Diagnostics;
- using System.IO;
- using Overthere.Interfaces;
- using System.Windows.Input;
- using System.Runtime.InteropServices;
-
- namespace Overthere
- {
- public class CmdConsole : IConsole, IDisposable
- {
- const int bufferSize = 5000;
-
- Process _cmdProcess;
-
- StreamWriter _inputStream;
- StreamReader _outputStream;
- StreamReader _errorStream;
-
- public CmdConsole()
- {
- string windowsDir = Environment.GetEnvironmentVariable("SystemRoot");
- string path = Path.Combine(windowsDir, "SysWOW64\\cmd.exe");
- if (!File.Exists(path))
- {
- path = Environment.GetEnvironmentVariable("ComSpec");
- }
-
- _cmdProcess = new Process();
- _cmdProcess.StartInfo.FileName = path;
- _cmdProcess.StartInfo.Arguments = "/K prompt $P$S$Q$G$S";
- _cmdProcess.StartInfo.CreateNoWindow = true;
- _cmdProcess.StartInfo.UseShellExecute = false;
- _cmdProcess.StartInfo.RedirectStandardOutput = true;
- _cmdProcess.StartInfo.RedirectStandardError = true;
- _cmdProcess.StartInfo.RedirectStandardInput = true;
- _cmdProcess.StartInfo.EnvironmentVariables["OTTEMP"] = Environment.GetEnvironmentVariable("TEMP");
-
- _cmdProcess.Start();
-
- _inputStream = _cmdProcess.StandardInput;
- _outputStream = _cmdProcess.StandardOutput;
- _errorStream = _cmdProcess.StandardError;
-
- byte[] outputBuffer = new byte[bufferSize];
- _outputStream.BaseStream.BeginRead(outputBuffer, 0, bufferSize, (ar) => DataReceived(ar, _outputStream.BaseStream, false), outputBuffer);
-
- byte[] errorBuffer = new byte[bufferSize];
- _errorStream.BaseStream.BeginRead(errorBuffer, 0, bufferSize, (ar) => DataReceived(ar, _errorStream.BaseStream, true), errorBuffer);
- }
-
- public void Dispose()
- {
- if (_cmdProcess != null)
- {
- _cmdProcess.Dispose();
- _cmdProcess = null;
-
- GC.SuppressFinalize(this);
- }
- }
-
- bool ignoreOutput = false;
-
- void DataReceived(IAsyncResult asyncResult, Stream stream, bool error)
- {
- int readCount = stream.EndRead(asyncResult);
-
- byte[] buffer = (byte[])asyncResult.AsyncState;
-
- if (readCount > 0 && !ignoreOutput)
- {
- string result = ASCIIEncoding.ASCII.GetString(buffer, 0, readCount);
-
- if (!error && Output != null)
- {
- Output(result);
- }
- else if (error && Error != null)
- {
- Error(result);
- }
- }
-
- stream.BeginRead(buffer, 0, buffer.Length, (ar) => DataReceived(ar, stream, error), buffer);
- }
-
- public void Input(string command)
- {
- _inputStream.Write(command);
- }
-
- public void InputCommand(string command)
- {
- Input(command + Environment.NewLine);
- }
-
- public event Action<string> Output;
- public event Action<string> Error;
-
- public string GetCurrentDirectory()
- {
- string path = Environment.GetEnvironmentVariable("TEMP") + "\\cd.txt";
-
- File.Delete(path);
-
- try
- {
- ignoreOutput = true;
- InputCommand("@echo off");
- InputCommand("cd > %OTTEMP%\\cd.txt");
- InputCommand("@echo on");
-
- for (int i = 0; i < 5; i++)
- {
- if (File.Exists(path))
- {
- try
- {
- string result = File.ReadAllText(path).Trim();
- File.Delete(path);
- return result;
- }
- catch (IOException)
- { }
- }
-
- System.Threading.Thread.Sleep(50);
- }
-
- return string.Empty;
- }
- finally
- {
- ignoreOutput = false;
- }
-
- }
-
- public IEnumerable<DirectoryInfo> GetDirectories(string directory)
- {
- try
- {
- DirectoryInfo dir = new DirectoryInfo(directory);
-
- return dir.GetDirectories().Where(d => (d.Attributes & FileAttributes.ReparsePoint) == 0).ToList();
- }
- catch
- {
- return new List<DirectoryInfo>();
- }
- }
-
- public IEnumerable<FileInfo> GetFiles(string directory)
- {
- try
- {
- DirectoryInfo dir = new DirectoryInfo(directory);
-
- return dir.GetFiles().Where(d => (d.Attributes & FileAttributes.ReparsePoint) == 0).ToList();
- }
- catch
- {
- return new List<FileInfo>();
- }
- }
-
- public void SendKey(Key key, ModifierKeys modifiers)
- {
- // Voodoo magic required to get the Ctrl+C/Break
- // to the cmdProcess without killing ourselves
- if ((key == Key.C || key == Key.Cancel) && KeyboardEx.IsControlDown)
- {
- UInt32 eventArg = key == Key.C ? CTRL_C_EVENT : CTRL_BREAK_EVENT;
-
- if (File.Exists("CtrlC.exe"))
- {
- Process process = new Process();
- process.StartInfo.FileName = "CtrlC.exe";
- process.StartInfo.Arguments = string.Format("{0} {1}", _cmdProcess.Id, eventArg);
- process.StartInfo.CreateNoWindow = true;
- process.StartInfo.UseShellExecute = false;
-
- process.Start();
- }
- }
- }
-
- public const UInt32 CTRL_C_EVENT = 0;
- public const UInt32 CTRL_BREAK_EVENT = 1;
- }
- }