void BeginBuildOperation(IEngineLogWriter logWriter, string binLogFilePath, MSBuildVerbosity verbosity, ProjectConfigurationInfo [] configurations) { // Start a new MSBuild build session, sending log to the provided writter RunSTA(delegate { BuildOperationStarted = true; // This property specifies the mapping between the solution configuration // and the project configurations engine.SetGlobalProperty("CurrentSolutionConfigurationContents", ProjectBuilder.GenerateSolutionConfigurationContents(configurations)); BuildParameters parameters = new BuildParameters(engine); sessionLogWriter = logWriter; loggerAdapter = new MSBuildLoggerAdapter(logWriter, verbosity); if (!string.IsNullOrEmpty(binLogFilePath)) { var binaryLogger = new BinaryLogger { Parameters = binLogFilePath, Verbosity = LoggerVerbosity.Diagnostic }; var loggers = new List <ILogger> (loggerAdapter.Loggers); loggers.Add(binaryLogger); parameters.Loggers = loggers; } else { parameters.Loggers = loggerAdapter.Loggers; } BuildManager.DefaultBuildManager.BeginBuild(parameters); }); }
/// <summary> /// Prepares the logging infrastructure /// </summary> public LoggerAdapter(IEngineLogWriter logWriter) { currentLogWriter = logWriter; if (currentLogWriter != null) { log.Clear(); logMessages.Clear(); flushingLog = false; flushTimer = new Timer(o => FlushLog()); } }
public MSBuildLoggerAdapter StartProjectSessionBuild(IEngineLogWriter logWriter) { // Sets the client logger to which to send build output. // In the client, each project has its own logger, // but in the builder there is a single logger for the // whole builder session. To send log to the correct // client logger, the logger will be changed every time // a new project build starts loggerAdapter.BuildResult.Clear(); loggerAdapter.EngineLogWriter = logWriter; return(loggerAdapter); }
void EndBuildOperation() { // End the MSBuild build session started in BeginBuildOperation RunSTA(delegate { engine.RemoveGlobalProperty("CurrentSolutionConfigurationContents"); BuildOperationStarted = false; BuildManager.DefaultBuildManager.EndBuild(); // Dispose the loggers. This will flush pending output. loggerAdapter.Dispose(); loggerAdapter = null; sessionLogWriter = null; }); }
void BeginBuildOperation(IEngineLogWriter logWriter, MSBuildVerbosity verbosity, ProjectConfigurationInfo [] configurations) { // Start a new MSBuild build session, sending log to the provided writter RunSTA(delegate { BuildOperationStarted = true; // This property specifies the mapping between the solution configuration // and the project configurations engine.SetGlobalProperty("CurrentSolutionConfigurationContents", ProjectBuilder.GenerateSolutionConfigurationContents(configurations)); BuildParameters parameters = new BuildParameters(engine); sessionLogWriter = logWriter; loggerAdapter = new MSBuildLoggerAdapter(logWriter, verbosity); parameters.Loggers = loggerAdapter.Loggers; BuildManager.DefaultBuildManager.BeginBuild(parameters); }); }
/// <summary> /// Flushes the log that has not yet been sent and disposes the logging infrastructure /// </summary> public void Dispose() { lock (flushLogLock) lock (log) { if (currentLogWriter != null) { try { flushTimer.Dispose(); FlushLog(); } catch { // Ignoree } finally { // This needs to be done inside the finally, to make sure it is called even in // the case the thread is being aborted. flushTimer = null; currentLogWriter = null; } } } }
public MSBuildLoggerAdapter(IEngineLogWriter logWriter, MSBuildVerbosity verbosity) : base(logWriter) { // LocalLogger will be used to collect build result information. // ConsoleLogger is used for the regular build output // TargetLogger collects and fordwards build events requested by the client var logger = new LocalLogger() { Adapter = this }; if (logWriter != null) { var consoleLogger = new ConsoleLogger(ProjectBuilder.GetVerbosity(verbosity), LogWrite, null, null); eventsLogger = new TargetLogger(logWriter.RequiredEvents, LogEvent); loggers = new ILogger [] { logger, consoleLogger, eventsLogger }; } else { loggers = new ILogger [] { logger }; } }
public MSBuildResult Run( ProjectConfigurationInfo[] configurations, IEngineLogWriter logWriter, MSBuildVerbosity verbosity, string[] runTargets, string[] evaluateItems, string[] evaluateProperties, Dictionary <string, string> globalProperties, int taskId) { MSBuildResult result = null; BuildEngine.RunSTA(taskId, delegate { try { var project = SetupProject(configurations); InitLogger(logWriter); buildEngine.Engine.UnregisterAllLoggers(); var logger = new LocalLogger(file); buildEngine.Engine.RegisterLogger(logger); if (logWriter != null) { buildEngine.Engine.RegisterLogger(consoleLogger); consoleLogger.Verbosity = GetVerbosity(verbosity); buildEngine.Engine.RegisterLogger(new TargetLogger(logWriter.RequiredEvents, LogEvent)); } if (runTargets != null && runTargets.Length > 0) { if (globalProperties != null) { foreach (var p in globalProperties) { project.GlobalProperties.SetProperty(p.Key, p.Value); } } // We are using this BuildProject overload and the BuildSettings.None argument as a workaround to // an xbuild bug which causes references to not be resolved after the project has been built once. buildEngine.Engine.BuildProject(project, runTargets, new Hashtable(), BuildSettings.None); if (globalProperties != null) { foreach (var p in globalProperties.Keys) { project.GlobalProperties.RemoveProperty(p); buildEngine.Engine.GlobalProperties.RemoveProperty(p); } } } result = new MSBuildResult(logger.BuildResult.ToArray()); if (evaluateProperties != null) { foreach (var name in evaluateProperties) { result.Properties [name] = project.GetEvaluatedProperty(name); } } if (evaluateItems != null) { foreach (var name in evaluateItems) { BuildItemGroup grp = project.GetEvaluatedItemsByName(name); var list = new List <MSBuildEvaluatedItem> (); foreach (BuildItem item in grp) { var evItem = new MSBuildEvaluatedItem(name, UnescapeString(item.FinalItemSpec)); foreach (DictionaryEntry de in (IDictionary)evaluatedMetadataField.GetValue(item)) { evItem.Metadata [(string)de.Key] = UnescapeString((string)de.Value); } list.Add(evItem); } result.Items[name] = list.ToArray(); } } } catch (InvalidProjectFileException ex) { var r = new MSBuildTargetResult( file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, ex.BaseMessage, ex.HelpKeyword); LogWriteLine(r.ToString()); result = new MSBuildResult(new [] { r }); } finally { DisposeLogger(); } }); return(result); }
public MSBuildResult Run( ProjectConfigurationInfo[] configurations, IEngineLogWriter logWriter, MSBuildVerbosity verbosity, string[] runTargets, string[] evaluateItems, string[] evaluateProperties, Dictionary <string, string> globalProperties, int taskId) { if (runTargets == null || runTargets.Length == 0) { throw new ArgumentException("runTargets is empty"); } MSBuildResult result = null; BuildEngine.RunSTA(taskId, delegate { Project project = null; Dictionary <string, string> originalGlobalProperties = null; MSBuildLoggerAdapter loggerAdapter; if (buildEngine.BuildOperationStarted) { loggerAdapter = buildEngine.StartProjectSessionBuild(logWriter); } else { loggerAdapter = new MSBuildLoggerAdapter(logWriter, verbosity); } try { project = SetupProject(configurations); if (globalProperties != null) { originalGlobalProperties = new Dictionary <string, string> (); foreach (var p in project.GlobalProperties) { originalGlobalProperties [p.Key] = p.Value; } if (globalProperties != null) { foreach (var p in globalProperties) { project.SetGlobalProperty(p.Key, p.Value); } } project.ReevaluateIfNecessary(); } // Building the project will create items and alter properties, so we use a new instance var pi = project.CreateProjectInstance(); Build(pi, runTargets, loggerAdapter.Loggers); result = new MSBuildResult(loggerAdapter.BuildResult.ToArray()); if (evaluateProperties != null) { foreach (var name in evaluateProperties) { var prop = pi.GetProperty(name); result.Properties [name] = prop != null? prop.EvaluatedValue : null; } } if (evaluateItems != null) { foreach (var name in evaluateItems) { var grp = pi.GetItems(name); var list = new List <MSBuildEvaluatedItem> (); foreach (var item in grp) { var evItem = new MSBuildEvaluatedItem(name, UnescapeString(item.EvaluatedInclude)); foreach (var metadataName in item.MetadataNames) { evItem.Metadata [metadataName] = UnescapeString(item.GetMetadataValue(metadataName)); } list.Add(evItem); } result.Items[name] = list.ToArray(); } } } catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex) { var r = new MSBuildTargetResult( file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, ex.BaseMessage, ex.HelpKeyword); loggerAdapter.LogWriteLine(r.ToString()); result = new MSBuildResult(new [] { r }); } finally { if (buildEngine.BuildOperationStarted) { buildEngine.EndProjectSessionBuild(); } else { loggerAdapter.Dispose(); } if (project != null && globalProperties != null) { foreach (var p in globalProperties) { project.RemoveGlobalProperty(p.Key); } foreach (var p in originalGlobalProperties) { project.SetGlobalProperty(p.Key, p.Value); } project.ReevaluateIfNecessary(); } } }); return(result); }
public MSBuildResult Run( ProjectConfigurationInfo[] configurations, IEngineLogWriter logWriter, MSBuildVerbosity verbosity, string[] runTargets, string[] evaluateItems, string[] evaluateProperties, Dictionary <string, string> globalProperties, int taskId) { if (runTargets == null || runTargets.Length == 0) { throw new ArgumentException("runTargets is empty"); } MSBuildResult result = null; BuildEngine.RunSTA(taskId, delegate { Project project = null; Dictionary <string, string> originalGlobalProperties = null; try { if (sdksPath != null) { Environment.SetEnvironmentVariable("MSBuildSDKsPath", sdksPath); } project = SetupProject(configurations); InitLogger(logWriter); ILogger[] loggers; var logger = new LocalLogger(file); if (logWriter != null) { var consoleLogger = new ConsoleLogger(GetVerbosity(verbosity), LogWrite, null, null); var eventLogger = new TargetLogger(logWriter.RequiredEvents, LogEvent); loggers = new ILogger[] { logger, consoleLogger, eventLogger }; } else { loggers = new ILogger[] { logger }; } if (globalProperties != null || sdksPath != null) { originalGlobalProperties = new Dictionary <string, string> (); foreach (var p in project.GlobalProperties) { originalGlobalProperties [p.Key] = p.Value; } if (globalProperties != null) { foreach (var p in globalProperties) { project.SetGlobalProperty(p.Key, p.Value); } } if (sdksPath != null) { project.SetGlobalProperty("MSBuildSDKsPath", sdksPath); } project.ReevaluateIfNecessary(); } //building the project will create items and alter properties, so we use a new instance var pi = project.CreateProjectInstance(); pi.Build(runTargets, loggers); result = new MSBuildResult(logger.BuildResult.ToArray()); if (evaluateProperties != null) { foreach (var name in evaluateProperties) { var prop = pi.GetProperty(name); result.Properties [name] = prop != null? prop.EvaluatedValue : null; } } if (evaluateItems != null) { foreach (var name in evaluateItems) { var grp = pi.GetItems(name); var list = new List <MSBuildEvaluatedItem> (); foreach (var item in grp) { var evItem = new MSBuildEvaluatedItem(name, UnescapeString(item.EvaluatedInclude)); foreach (var m in item.Metadata) { evItem.Metadata [m.Name] = UnescapeString(m.EvaluatedValue); } list.Add(evItem); } result.Items[name] = list.ToArray(); } } } catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex) { var r = new MSBuildTargetResult( file, false, ex.ErrorSubcategory, ex.ErrorCode, ex.ProjectFile, ex.LineNumber, ex.ColumnNumber, ex.EndLineNumber, ex.EndColumnNumber, ex.BaseMessage, ex.HelpKeyword); LogWriteLine(r.ToString()); result = new MSBuildResult(new [] { r }); } finally { DisposeLogger(); if (project != null && globalProperties != null) { foreach (var p in globalProperties) { project.RemoveGlobalProperty(p.Key); } foreach (var p in originalGlobalProperties) { project.SetGlobalProperty(p.Key, p.Value); } project.ReevaluateIfNecessary(); } } }); return(result); }
void BeginBuildOperation(IEngineLogWriter logWriter, MSBuildVerbosity verbosity, ProjectConfigurationInfo [] configurations) { }