using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestExecWin
{
class Executor : IExecute
{
public static EnvDTE80.DTE2 dte;
private IMainEvents m_mainEvents;
private IEventReceiver m_evenReceiver;
private System.Diagnostics.Process m_process = null;
private EnvDTE.OutputWindowPane m_outputPane = null;
bool m_catchStdOutAndStdErr = true;
bool m_getNotificationWhenProcessTerminates = true;
private bool m_checkForMemoryLeaks = false;
public Executor(IMainEvents in_mainEvents, IEventReceiver in_eventReceiver)
{
m_mainEvents = in_mainEvents;
m_evenReceiver = in_eventReceiver;
}
public void SetMemLeakCheck(bool in_state)
{
m_checkForMemoryLeaks = in_state;
}
public void StartProcess(string exePath, string args, string workDir)
{
try
{
if (!System.IO.File.Exists(exePath))
{
m_mainEvents.OnTestTerminated(false, exePath, false, new TimeSpan(0));
WriteLine(1, "Executable not found: " + exePath);
return;
}
if (m_outputPane == null)
{
EnvDTE.OutputWindow ow = dte.ToolWindows.OutputWindow;
m_outputPane = ow.OutputWindowPanes.Add("Run UnitTest");
}
m_outputPane.Activate();
m_outputPane.Clear();
m_process = new System.Diagnostics.Process();
m_process.StartInfo.FileName = exePath;
m_process.StartInfo.WorkingDirectory = workDir;
m_process.StartInfo.Arguments = args.Trim();
if (m_getNotificationWhenProcessTerminates)
{
m_process.Exited += new System.EventHandler(Process_Exited);
m_process.EnableRaisingEvents = true;
}
if (m_catchStdOutAndStdErr)
{
m_process.StartInfo.UseShellExecute = false;
m_process.StartInfo.RedirectStandardOutput = true;
m_process.StartInfo.RedirectStandardError = true;
m_process.StartInfo.CreateNoWindow = true;
m_process.OutputDataReceived += new System.Diagnostics.
DataReceivedEventHandler(StandardOutputReceiver);
m_process.ErrorDataReceived += new System.Diagnostics.
DataReceivedEventHandler(StandardErrorReceiver);
}
m_process.Start();
if (m_catchStdOutAndStdErr)
{
m_process.BeginOutputReadLine();
m_process.BeginErrorReadLine();
}
WriteLine(2, "Started " + m_process.StartInfo.FileName);
}
catch (Exception e)
{
string info = "EXCEPTION: Could not start executable " + exePath + " " + e.ToString();
WriteLine(1, info);
m_mainEvents.OnTestTerminated(false, exePath, false, new TimeSpan(0));
}
}
public void Process_Exited(object sender, System.EventArgs e)
{
try
{
string info = string.Format("Exit time: {0}" +
" Exit code: {1}", m_process.ExitTime, m_process.ExitCode);
TimeSpan executionTime = m_process.ExitTime - m_process.StartTime;
WriteLine(2, info);
bool memLeaksDetected = false;
if (m_checkForMemoryLeaks)
{
WriteLine(3, "Process_Exited: Checking mem leaks...");
System.Threading.Thread.Sleep(500);
WriteLine(3, "Process_Exited: .. after sleep");
var sel = m_outputPane.TextDocument.Selection;
WriteLine(3, "Process_Exited: selection acquired");
sel.SelectAll();
WriteLine(3, "Process_Exited: all selected");
if ((sel.Text.Contains("Detected memory leaks")) || (sel.Text.Contains("Object dump complete")))
{
memLeaksDetected = true;
WriteLine(3, "Process_Exited: ERROR: Memory leaks detected!");
}
}
m_mainEvents.OnTestTerminated(m_process.ExitCode == 0, m_process.StartInfo.Arguments, memLeaksDetected, executionTime);
}
catch (Exception)
{
string info = "EXCEPTION within Process_Exited: ";
WriteLine(1, info);
m_mainEvents.OnTestTerminated(false, m_process.StartInfo.Arguments, false, new TimeSpan(0));
}
}
public void KillRunningProcess()
{
try
{
if (m_process == null)
return;
WriteLine(1, "Killing " + m_process.ProcessName);
m_process.Kill();
}
catch (Exception e)
{
string info = "EXCEPTION: " + e.ToString();
WriteLine(2, info);
}
}
private void StandardOutputReceiver(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data))
{
if (m_outputPane != null)
m_outputPane.OutputString(outLine.Data + System.Environment.NewLine);
}
}
private void StandardErrorReceiver(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs errLine)
{
if (!string.IsNullOrEmpty(errLine.Data))
{
if (m_outputPane != null)
m_outputPane.OutputString("Error> " + errLine.Data + System.Environment.NewLine);
}
}
private void WriteLine(int in_outputLevel, String in_info)
{
m_evenReceiver.WriteLine(in_outputLevel, in_info);
}
}
}