/// <summary> /// Attempts to get the current <see cref="ProjectInstance"/> of the executing task via reflection. /// </summary> /// <returns>A <see cref="ProjectInstance"/> object if one could be determined, otherwise null..</returns> private ProjectInstance GetProjectInstance() { try { FieldInfo requestEntryFieldInfo = BuildEngine.GetType().GetField("_requestEntry", BindingFlags.Instance | BindingFlags.NonPublic); if (requestEntryFieldInfo != null && BuildRequestEntryTypeLazy.Value != null && BuildRequestConfigurationTypeLazy.Value != null) { object requestEntry = requestEntryFieldInfo.GetValue(BuildEngine); if (requestEntry != null && BuildRequestEntryRequestConfigurationPropertyInfo.Value != null) { object requestConfiguration = BuildRequestEntryRequestConfigurationPropertyInfo.Value.GetValue(requestEntry); if (requestConfiguration != null && BuildRequestConfigurationProjectPropertyInfo.Value != null) { return(BuildRequestConfigurationProjectPropertyInfo.Value.GetValue(requestConfiguration) as ProjectInstance); } } } } catch { // Ignored because we never want this method to throw since its using reflection to access internal members that could go away with any future release of MSBuild } return(null); }
private ProjectInstance GetProjectInstance() { var type1 = BuildEngine.GetType(); var field1 = type1.GetField("targetBuilderCallback", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); if ((object)field1 == null) { field1 = type1.GetField("_targetBuilderCallback", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); } var fieldInfo1 = field1; if (fieldInfo1 == null) { throw new Exception("Could not extract targetBuilderCallback from " + type1.FullName); } object obj = fieldInfo1.GetValue((object)this.BuildEngine); Type type2 = obj.GetType(); FieldInfo field2 = type2.GetField("projectInstance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); if ((object)field2 == null) { field2 = type2.GetField("_projectInstance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); } FieldInfo fieldInfo2 = field2; if (fieldInfo2 == null) { throw new Exception("Could not extract projectInstance from " + type2.FullName); } return((ProjectInstance)fieldInfo2.GetValue(obj)); }
public override bool Execute() { if (!AllowFailureWithoutError.Equals("Default")) { BuildEngine.GetType().GetProperty("AllowFailureWithoutError").SetValue(BuildEngine, AllowFailureWithoutError.Equals("True")); } return(false); }
/// <summary> /// Executes the task - gets all build properties from <see cref="IBuildEngine"/> (using the reflection as the access to information is not public) /// and dump project build global and project properties to build output. /// </summary> /// <returns>True</returns> public override bool Execute() { if (DebugTasks) { //Wait for debugger Log.LogMessage( MessageImportance.High, $"Debugging task {GetType().Name}, set the breakpoint and attach debugger to process with PID = {System.Diagnostics.Process.GetCurrentProcess().Id}"); while (!System.Diagnostics.Debugger.IsAttached) { Thread.Sleep(1000); } } //Get to the ProjectInstance var requestEntryField = BuildEngine.GetType().GetField("_requestEntry", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance); var requestEntry = requestEntryField?.GetValue(BuildEngine); var requestConfigurationProperty = requestEntry?.GetType().GetProperty("RequestConfiguration", BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance); var requestConfiguration = requestConfigurationProperty?.GetValue(requestEntry); var projectProperty = requestConfiguration?.GetType().GetProperty("Project", BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.Instance); var projectRaw = projectProperty?.GetValue(requestConfiguration); var project = projectRaw as ProjectInstance; //Dump global properties var globalProperties = project?.GlobalProperties; if (globalProperties != null) { var globalPropertiesList = globalProperties.ToList(); globalPropertiesList.Sort((a, b) => string.CompareOrdinal(a.Key, b.Key)); foreach (var globalProperty in globalPropertiesList) { Log.LogMessage(MessageImportance.High, $"Global Property: {globalProperty.Key} = {globalProperty.Value}"); } } //Dump project properties var projectProperties = project?.Properties; // ReSharper disable once InvertIf if (projectProperties != null) { var propertyList = projectProperties.ToList(); propertyList.Sort((a, b) => string.CompareOrdinal(a.Name, b.Name)); foreach (var propertyInstance in propertyList) { Log.LogMessage(MessageImportance.High, $"Project Property: {propertyInstance.Name} = {propertyInstance.EvaluatedValue}"); } } return(true); }
/// <summary> /// Introspects the current project and retrieves its /// properties and currently building targets. /// </summary> public override bool Execute() { ProjectInstance project; IEnumerable <object> targets; var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; var engineType = BuildEngine.GetType(); var callbackField = engineType.GetField("targetBuilderCallback", flags); if (callbackField != null) { // .NET field naming convention. var callback = callbackField.GetValue(BuildEngine); var projectField = callback.GetType().GetField("projectInstance", flags); project = (ProjectInstance)projectField.GetValue(callback); var targetsField = callback.GetType().GetField("targetsToBuild", flags); targets = (IEnumerable <object>)targetsField.GetValue(callback); } else { callbackField = engineType.GetField("_targetBuilderCallback", flags); if (callbackField == null) { throw new NotSupportedException("Failed to introspect current MSBuild Engine."); } // OSS field naming convention. var callback = callbackField.GetValue(BuildEngine); var projectField = callback.GetType().GetField("_projectInstance", flags); project = (ProjectInstance)projectField.GetValue(callback); var targetsField = callback.GetType().GetField("_targetsToBuild", flags); targets = (IEnumerable <object>)targetsField.GetValue(callback); } Properties = new TaskItem(project.ProjectFileLocation.File, project.Properties.ToDictionary( prop => prop.Name, prop => prop.EvaluatedValue)); if (targets.Any()) { var entryType = targets.First().GetType(); var nameField = entryType.GetProperty("Name", flags); Targets = targets .Select(entry => (string)nameField.GetValue(entry)) .Where(target => !project.InitialTargets.Contains(target)) .Select(target => new TaskItem(target)) .ToArray(); } else { Targets = new ITaskItem[0]; } return(true); }
/// <summary> /// Inspired by http://stackoverflow.com/questions/3043531/when-implementing-a-microsoft-build-utilities-task-how-to-i-get-access-to-the-va /// </summary> /// <returns></returns> private ProjectInstance GetProjectInstance() { var buildEngineType = BuildEngine.GetType(); var targetBuilderCallbackField = buildEngineType.GetField("targetBuilderCallback", BindingFlags) ?? buildEngineType.GetField("_targetBuilderCallback", BindingFlags); if (targetBuilderCallbackField == null) { throw new Exception("Could not extract targetBuilderCallback from " + buildEngineType.FullName); } var targetBuilderCallback = targetBuilderCallbackField.GetValue(BuildEngine); var targetCallbackType = targetBuilderCallback.GetType(); var projectInstanceField = targetCallbackType.GetField("projectInstance", BindingFlags) ?? targetCallbackType.GetField("_projectInstance", BindingFlags); if (projectInstanceField == null) { throw new Exception("Could not extract projectInstance from " + targetCallbackType.FullName); } return((ProjectInstance)projectInstanceField.GetValue(targetBuilderCallback)); }
private IEnumerable <KeyValuePair <string, string> > GetMsBuildProperties() { // We need to use reflection to get // the build properties out of MSBuild. try { int version = BuildEngine.GetType().Assembly.GetName().Version.Major; // The name of the field that stores the IBuildComponentHost changed in MSBuild 14. object host = BuildEngine.GetType().InvokeMember( (version >= 14) ? "_host" : "host", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance, null, BuildEngine, new object[] { } ); object buildParameters = host.GetType().GetInterface("IBuildComponentHost").InvokeMember( "BuildParameters", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, host, new object[] { } ); object globalProperties = buildParameters.GetType().InvokeMember( "GlobalProperties", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, buildParameters, new object[] { } ); return((IDictionary <string, string>)globalProperties); } catch (Exception ex) { Log.LogError("Could not get global properties from MSBuild: " + ex.Message); return(null); } }
/// <summary> /// Get the global property from the IBuildEngine API. /// </summary> /// <returns>Returns the dictionary with the global properties if they can be accessed. <see langword="null"/> otherwise, which means that the msbuild version doesn't implement this API. </returns> internal IReadOnlyDictionary <string, string> GetGlobalProperties(Common.ILogger logger) { #if IS_CORECLR // MSBuild 16.5 and above has a method to get the global properties, older versions do not IReadOnlyDictionary <string, string> msBuildGlobalProperties = BuildEngine is IBuildEngine6 buildEngine6 ? buildEngine6.GetGlobalProperties() : null; #else IReadOnlyDictionary <string, string> msBuildGlobalProperties = null; // MSBuild 16.5 added a new interface, IBuildEngine6, which has a GetGlobalProperties() method. However, we compile against // Microsoft.Build.Framework version 4.0 when targeting .NET Framework, so reflection is required since type checking // can't be done at compile time var getGlobalPropertiesMethod = BuildEngine.GetType().GetMethod("GetGlobalProperties", BindingFlags.Instance | BindingFlags.Public); if (getGlobalPropertiesMethod != null) { try { if (getGlobalPropertiesMethod.Invoke(BuildEngine, null) is IReadOnlyDictionary <string, string> globalProperties) { msBuildGlobalProperties = globalProperties; } } catch (Exception e) { // This is an unexpected error, so we don't localize. logger.LogError($"Internal Error. Failed calling the Microsoft.Build.Framework.IBuildEngine6.GetGlobalProperties method via reflection. Unable to determine the global properties.{e}"); } } else { // This is an unexpected error, so we don't localize. logger.LogError($"Internal Error. Failed calling the Microsoft.Build.Framework.IBuildEngine6.GetGlobalProperties method via reflection. Unable to determine the global properties."); } #endif return(msBuildGlobalProperties); }
public override bool Execute() { var traceEnabledValue = Environment.GetEnvironmentVariable("VSTEST_BUILD_TRACE"); Tracing.traceEnabled = !string.IsNullOrEmpty(traceEnabledValue) && traceEnabledValue.Equals("1", StringComparison.OrdinalIgnoreCase); var debugEnabled = Environment.GetEnvironmentVariable("VSTEST_BUILD_DEBUG"); if (!string.IsNullOrEmpty(debugEnabled) && debugEnabled.Equals("1", StringComparison.Ordinal)) { Console.WriteLine("Waiting for debugger attach..."); var currentProcess = Process.GetCurrentProcess(); Console.WriteLine(string.Format("Process Id: {0}, Name: {1}", currentProcess.Id, currentProcess.ProcessName)); while (!Debugger.IsAttached) { Thread.Sleep(1000); } Debugger.Break(); } // Avoid logging "Task returned false but did not log an error." on test failure, because we don't // write MSBuild error. https://github.com/dotnet/msbuild/blob/51a1071f8871e0c93afbaf1b2ac2c9e59c7b6491/src/Framework/IBuildEngine7.cs#L12 var allowfailureWithoutError = BuildEngine.GetType().GetProperty("AllowFailureWithoutError"); allowfailureWithoutError?.SetValue(BuildEngine, true); vsTestForwardingApp = new VSTestForwardingApp(this.VSTestConsolePath, this.CreateArgument()); if (!string.IsNullOrEmpty(this.VSTestFramework)) { Console.WriteLine(Resources.TestRunningSummary, this.TestFileFullPath, this.VSTestFramework); } return(vsTestForwardingApp.Execute() == 0); }
public override bool Execute() { BuildEngine.GetType().GetProperty("AllowFailureWithoutError").SetValue(BuildEngine, EnableDefaultFailure); return(false); }