/// <summary> /// Do the work of actually instantiating and running the task. /// </summary> private OutOfProcTaskHostTaskResult InstantiateAndExecuteTask ( IBuildEngine oopTaskHostNode, LoadedType taskType, string taskName, string taskLocation, string taskFile, int taskLine, int taskColumn, #if FEATURE_APPDOMAIN AppDomainSetup appDomainSetup, #endif IDictionary <string, TaskParameter> taskParams ) { #if FEATURE_APPDOMAIN _taskAppDomain = null; #endif wrappedTask = null; try { wrappedTask = TaskLoader.CreateTask(taskType, taskName, taskFile, taskLine, taskColumn, new TaskLoader.LogError(LogErrorDelegate), #if FEATURE_APPDOMAIN appDomainSetup, #endif true /* always out of proc */ #if FEATURE_APPDOMAIN , out _taskAppDomain #endif ); wrappedTask.BuildEngine = oopTaskHostNode; } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } Exception exceptionToReturn = e; // If it's a TargetInvocationException, we only care about the contents of the inner exception, // so just save that instead. if (e is TargetInvocationException) { exceptionToReturn = e.InnerException; } return(new OutOfProcTaskHostTaskResult ( TaskCompleteType.CrashedDuringInitialization, exceptionToReturn, "TaskInstantiationFailureError", new string[] { taskName, taskLocation, String.Empty } )); } foreach (KeyValuePair <string, TaskParameter> param in taskParams) { try { PropertyInfo paramInfo = wrappedTask.GetType().GetProperty(param.Key, BindingFlags.Instance | BindingFlags.Public); paramInfo.SetValue(wrappedTask, param.Value?.WrappedParameter, null); } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } Exception exceptionToReturn = e; // If it's a TargetInvocationException, we only care about the contents of the inner exception, // so just save that instead. if (e is TargetInvocationException) { exceptionToReturn = e.InnerException; } return(new OutOfProcTaskHostTaskResult ( TaskCompleteType.CrashedDuringInitialization, exceptionToReturn, "InvalidTaskAttributeError", new string[] { param.Key, param.Value.ToString(), taskName } )); } } bool success = false; try { if (CancelPending) { return(new OutOfProcTaskHostTaskResult(TaskCompleteType.Failure)); } // If it didn't crash and return before now, we're clear to go ahead and execute here. success = wrappedTask.Execute(); } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } return(new OutOfProcTaskHostTaskResult(TaskCompleteType.CrashedDuringExecution, e)); } PropertyInfo[] finalPropertyValues = wrappedTask.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); IDictionary <string, Object> finalParameterValues = new Dictionary <string, Object>(StringComparer.OrdinalIgnoreCase); foreach (PropertyInfo value in finalPropertyValues) { // only record outputs if (value.GetCustomAttributes(typeof(OutputAttribute), true).Count() > 0) { try { finalParameterValues[value.Name] = value.GetValue(wrappedTask, null); } catch (Exception e) { if (ExceptionHandling.IsCriticalException(e)) { throw; } // If it's not a critical exception, we assume there's some sort of problem in the parameter getter -- // so save the exception, and we'll re-throw once we're back on the main node side of the // communications pipe. finalParameterValues[value.Name] = e; } } } return(new OutOfProcTaskHostTaskResult(success ? TaskCompleteType.Success : TaskCompleteType.Failure, finalParameterValues)); }
/// <summary> /// Create an instance of the wrapped ITask for a batch run of the task. /// </summary> internal ITask CreateTaskInstance(ElementLocation taskLocation, TaskLoggingContext taskLoggingContext, IBuildComponentHost buildComponentHost, IDictionary <string, string> taskIdentityParameters, #if FEATURE_APPDOMAIN AppDomainSetup appDomainSetup, #endif bool isOutOfProc) { bool useTaskFactory = false; IDictionary <string, string> mergedParameters = null; _taskLoggingContext = taskLoggingContext; // Optimization for the common (vanilla AssemblyTaskFactory) case -- only calculate // the task factory parameters if we have any to calculate; otherwise even if we // still launch the task factory, it will be with parameters corresponding to the // current process. if ((_factoryIdentityParameters != null && _factoryIdentityParameters.Count > 0) || (taskIdentityParameters != null && taskIdentityParameters.Count > 0)) { VerifyThrowIdentityParametersValid(taskIdentityParameters, taskLocation, _taskName, "MSBuildRuntime", "MSBuildArchitecture"); mergedParameters = MergeTaskFactoryParameterSets(_factoryIdentityParameters, taskIdentityParameters); useTaskFactory = !NativeMethodsShared.IsMono && (_taskHostFactoryExplicitlyRequested || !TaskHostParametersMatchCurrentProcess(mergedParameters)); } else { // if we don't have any task host parameters specified on either the using task or the // task invocation, then we will run in-proc UNLESS "TaskHostFactory" is explicitly specified // as the task factory. useTaskFactory = _taskHostFactoryExplicitlyRequested; } if (useTaskFactory) { ErrorUtilities.VerifyThrowInternalNull(buildComponentHost, "buildComponentHost"); mergedParameters = mergedParameters ?? new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); string runtime = null; string architecture = null; if (!mergedParameters.TryGetValue(XMakeAttributes.runtime, out runtime)) { mergedParameters[XMakeAttributes.runtime] = XMakeAttributes.MSBuildRuntimeValues.clr4; } if (!mergedParameters.TryGetValue(XMakeAttributes.architecture, out architecture)) { mergedParameters[XMakeAttributes.architecture] = XMakeAttributes.GetCurrentMSBuildArchitecture(); } TaskHostTask task = new TaskHostTask(taskLocation, taskLoggingContext, buildComponentHost, mergedParameters, _loadedType #if FEATURE_APPDOMAIN , appDomainSetup #endif ); return(task); } else { #if FEATURE_APPDOMAIN AppDomain taskAppDomain = null; #endif ITask taskInstance = TaskLoader.CreateTask(_loadedType, _taskName, taskLocation.File, taskLocation.Line, taskLocation.Column, new TaskLoader.LogError(ErrorLoggingDelegate) #if FEATURE_APPDOMAIN , appDomainSetup #endif , isOutOfProc #if FEATURE_APPDOMAIN , out taskAppDomain #endif ); #if FEATURE_APPDOMAIN if (taskAppDomain != null) { _tasksAndAppDomains[taskInstance] = taskAppDomain; } #endif return(taskInstance); } }
private static int RunTarget() { StaticTarget target; var ser = new DataContractJsonSerializer(typeof(StaticTarget)); using (var memoryStream = new MemoryStream()) { using (var writer = new StreamWriter(memoryStream, Encoding.Default, 1024 * 4, true)) { string s; while ((s = Console.ReadLine()) != null) { writer.WriteLine(s); } } memoryStream.Position = 0; target = (StaticTarget)ser.ReadObject(memoryStream); } foreach (StaticTarget.Task staticTask in target.Tasks) { Type type; if (staticTask.AssemblyFile != null) { AssemblyName an = AssemblyName.GetAssemblyName(staticTask.AssemblyFile); if (an == null) { Console.WriteLine("Caouldn't get assembly name for assembly file: " + staticTask.AssemblyFile); return(1); } Assembly a = Assembly.Load(an); if (a == null) { Console.WriteLine("Couldn't loaded assembly for assembly: " + an.FullName + " from file: " + staticTask.AssemblyFile); return(1); } type = a.GetType(staticTask.Name.Split(',')[0]); if (type == null) { Console.WriteLine("Couldn't create type for string: " + staticTask.Name.Split(',')[0] + " assembly file: " + (staticTask.AssemblyFile ?? "null") + " and assembly name: " + (staticTask.AssemblyName ?? "null")); Console.WriteLine("Types in the assembly:\n" + string.Join(",\n", a.GetTypes().Select(availableType => availableType.FullName))); return(1); } } else { type = Type.GetType(staticTask.Name); if (type == null) { Console.WriteLine("Couldn't create type for string: " + staticTask.Name + " assembly file: " + (staticTask.AssemblyFile ?? "null") + " and assembly name: " + (staticTask.AssemblyName ?? "null")); return(1); } } var assemblyLoadInfo = AssemblyLoadInfo.Create(assemblyFile: staticTask.AssemblyFile, assemblyName: staticTask.AssemblyName); if (assemblyLoadInfo == null) { Console.WriteLine("Couldn't create type for assembly file: " + (staticTask.AssemblyFile ?? "null") + " and name: " + (staticTask.AssemblyName ?? "null")); return(1); } LoadedType loadedType = new LoadedType(type, assemblyLoadInfo, null); TaskPropertyInfo[] taskProperties = AssemblyTaskFactory.GetTaskParameters(loadedType); ITask task = TaskLoader.CreateTask(loadedType, staticTask.Name, staticTask.AssemblyName, 0, 0, null #if FEATURE_APPDOMAIN , null #endif , false #if FEATURE_APPDOMAIN , out var appDomain #endif ); foreach (var parameter in staticTask.Parameters) { var taskPropertyInfo = taskProperties.FirstOrDefault(property => property.Name == parameter.Key); if (taskPropertyInfo == null) { Console.Error.WriteLine("Could not find property: \"" + parameter.Key + "\" for task + \"" + staticTask.Name + "\""); return(1); } StaticTarget.Task.ParameterType parameterType = parameter.Value.ParameterType; switch (parameterType) { case StaticTarget.Task.ParameterType.Primitive: object value = GetTypedValue(parameter.Value.Primitive.Type, parameter.Value.Primitive.Value); TaskFactoryWrapper.SetPropertyValue(task, taskPropertyInfo, value); break; case StaticTarget.Task.ParameterType.Primitives: var values = GetTypedArrayValue(parameter.Value.Primitives.Type, parameter.Value.Primitives.Values); TaskFactoryWrapper.SetPropertyValue(task, taskPropertyInfo, values); break; case StaticTarget.Task.ParameterType.TaskItem: TaskFactoryWrapper.SetPropertyValue(task, taskPropertyInfo, new TaskItem(parameter.Value.TaskItem.ItemSpec, parameter.Value.TaskItem.Metadata)); break; case StaticTarget.Task.ParameterType.TaskItems: ITaskItem[] taskItems = parameter.Value.TaskItems.Select(taskItem => new TaskItem(taskItem.ItemSpec, taskItem.Metadata)).ToArray(); TaskFactoryWrapper.SetPropertyValue(task, taskPropertyInfo, taskItems); break; } } task.BuildEngine = new SimpleBuildEngine(); try { // MSBuild ignores this return value :( task.Execute(); } catch (Exception e) { Console.Error.WriteLine("TASK ERROR: " + e); return(1); } } return(0); }