using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Build.Utilities; using System.Diagnostics; using MessageImportance = Microsoft.Build.Framework.MessageImportance; using Microsoft.Build.Framework; namespace Cosmos.Build.MSBuild { public enum WriteType { Warning, Error, Message, // only issued on console Info } public abstract class BaseToolTask : AppDomainIsolatedTask { protected bool ExecuteTool(string workingDir, string filename, string arguments, string name) { var xProcessStartInfo = new ProcessStartInfo(); xProcessStartInfo.WorkingDirectory = workingDir; xProcessStartInfo.FileName = filename; xProcessStartInfo.Arguments = arguments; xProcessStartInfo.UseShellExecute = false; xProcessStartInfo.RedirectStandardOutput = true; xProcessStartInfo.RedirectStandardError = true; xProcessStartInfo.CreateNoWindow = true; using (var xProcess = new Process()) { xProcess.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data != null) mErrors.Add(e.Data); }; xProcess.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data != null) mOutput.Add(e.Data); }; xProcess.StartInfo = xProcessStartInfo; mErrors = new List(); mOutput = new List(); xProcess.Start(); xProcess.BeginErrorReadLine(); xProcess.BeginOutputReadLine(); xProcess.WaitForExit(15 * 60 * 1000); // wait 15 minutes if (xProcess.ExitCode != 0) { if (!xProcess.HasExited) { xProcess.Kill(); Log.LogError("{0} timed out.", name); } else { Log.LogError("Error occurred while invoking {0}.", name); } } WriteType typ; foreach (var xError in mErrors) { string error = xError; if(ExtendLineError(xProcess.ExitCode, ref error, out typ)) { Logs(typ, error); } } foreach (var xOutput in mOutput) { string output = xOutput; if (ExtendLineError(xProcess.ExitCode, ref output, out typ)) { Logs(typ, output); } } return xProcess.ExitCode == 0; } } private List mErrors; private List mOutput; public virtual bool ExtendLineError(int exitCode, ref string errorMessage, out WriteType typ) { typ = WriteType.Error; if (exitCode == 0) return false; return true; } public virtual bool ExtendLineOutput(int exitCode, ref string errorMessage, out WriteType typ) { typ = WriteType.Info; return true; } public void Logs(WriteType typ, string message) { switch (typ) { case WriteType.Warning: Log.LogWarning(message); break; case WriteType.Error: Log.LogError(message); break; case WriteType.Message: Log.LogMessage(message); break; case WriteType.Info: // changed IDEBuildLogger.cs for this behavior of add to ErrorList Messages Log.LogMessage(MessageImportance.High, message); break; default: Log.LogError(message); break; } } } }