public void Regress640476PartialName() { string forwardingLoggerLocation = typeof(Microsoft.Build.Logging.ConfigurableForwardingLogger).Assembly.Location; TypeLoader loader = new TypeLoader(new TypeFilter(IsForwardingLoggerClass)); LoadedType loadedType = loader.Load("ConfigurableForwardingLogger", AssemblyLoadInfo.Create(null, forwardingLoggerLocation)); Assert.IsNotNull(loadedType); Assert.IsTrue(loadedType.Assembly.AssemblyLocation.Equals(forwardingLoggerLocation, StringComparison.OrdinalIgnoreCase)); string fileLoggerLocation = typeof(Microsoft.Build.Logging.FileLogger).Assembly.Location; loader = new TypeLoader(new TypeFilter(IsLoggerClass)); loadedType = loader.Load("FileLogger", AssemblyLoadInfo.Create(null, fileLoggerLocation)); Assert.IsNotNull(loadedType); Assert.IsTrue(loadedType.Assembly.AssemblyLocation.Equals(fileLoggerLocation, StringComparison.OrdinalIgnoreCase)); }
public void NoTypeNamePicksFirstType() { Type forwardingLoggerType = typeof(Microsoft.Build.Logging.ConfigurableForwardingLogger); string forwardingLoggerAssemblyLocation = forwardingLoggerType.Assembly.Location; TypeFilter forwardingLoggerfilter = new TypeFilter(IsForwardingLoggerClass); Type firstPublicType = FirstPublicDesiredType(forwardingLoggerfilter, forwardingLoggerAssemblyLocation); TypeLoader loader = new TypeLoader(forwardingLoggerfilter); LoadedType loadedType = loader.Load(String.Empty, AssemblyLoadInfo.Create(null, forwardingLoggerAssemblyLocation)); Assert.IsNotNull(loadedType); Assert.IsTrue(loadedType.Assembly.AssemblyLocation.Equals(forwardingLoggerAssemblyLocation, StringComparison.OrdinalIgnoreCase)); Assert.IsTrue(loadedType.Type.Equals(firstPublicType)); Type fileLoggerType = typeof(Microsoft.Build.Logging.FileLogger); string fileLoggerAssemblyLocation = forwardingLoggerType.Assembly.Location; TypeFilter fileLoggerfilter = new TypeFilter(IsLoggerClass); firstPublicType = FirstPublicDesiredType(fileLoggerfilter, fileLoggerAssemblyLocation); loader = new TypeLoader(fileLoggerfilter); loadedType = loader.Load(String.Empty, AssemblyLoadInfo.Create(null, fileLoggerAssemblyLocation)); Assert.IsNotNull(loadedType); Assert.IsTrue(loadedType.Assembly.AssemblyLocation.Equals(fileLoggerAssemblyLocation, StringComparison.OrdinalIgnoreCase)); Assert.IsTrue(loadedType.Type.Equals(firstPublicType)); }
/// <summary> /// Initialize the host object /// </summary> /// <param name="throwOnExecute">Should the task throw when executed</param> private void InitializeHost(bool throwOnExecute) { _loggingService = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1) as ILoggingService; _logger = new MockLogger(); _loggingService.RegisterLogger(_logger); _host = new TaskExecutionHost(); TargetLoggingContext tlc = new TargetLoggingContext(_loggingService, new BuildEventContext(1, 1, BuildEventContext.InvalidProjectContextId, 1)); // Set up a temporary project and add some items to it. ProjectInstance project = CreateTestProject(); TypeLoader typeLoader = new TypeLoader(new TypeFilter(IsTaskFactoryClass)); AssemblyLoadInfo loadInfo = AssemblyLoadInfo.Create(Assembly.GetAssembly(typeof(TaskBuilderTestTask.TaskBuilderTestTaskFactory)).FullName, null); LoadedType loadedType = new LoadedType(typeof(TaskBuilderTestTask.TaskBuilderTestTaskFactory), loadInfo); TaskBuilderTestTask.TaskBuilderTestTaskFactory taskFactory = new TaskBuilderTestTask.TaskBuilderTestTaskFactory(); taskFactory.ThrowOnExecute = throwOnExecute; string taskName = "TaskBuilderTestTask"; (_host as TaskExecutionHost)._UNITTESTONLY_TaskFactoryWrapper = new TaskFactoryWrapper(taskFactory, loadedType, taskName, null); _host.InitializeForTask ( this, tlc, project, taskName, ElementLocation.Create("none", 1, 1), this, false, null, false, CancellationToken.None ); ProjectTaskInstance taskInstance = project.Targets["foo"].Tasks.First(); TaskLoggingContext talc = tlc.LogTaskBatchStarted(".", taskInstance); ItemDictionary<ProjectItemInstance> itemsByName = new ItemDictionary<ProjectItemInstance>(); ProjectItemInstance item = new ProjectItemInstance(project, "ItemListContainingOneItem", "a.cs", "."); item.SetMetadata("Culture", "fr-fr"); itemsByName.Add(item); _oneItem = new ITaskItem[] { new TaskItem(item) }; item = new ProjectItemInstance(project, "ItemListContainingTwoItems", "b.cs", "."); ProjectItemInstance item2 = new ProjectItemInstance(project, "ItemListContainingTwoItems", "c.cs", "."); item.SetMetadata("HintPath", "c:\\foo"); item2.SetMetadata("HintPath", "c:\\bar"); itemsByName.Add(item); itemsByName.Add(item2); _twoItems = new ITaskItem[] { new TaskItem(item), new TaskItem(item2) }; _bucket = new ItemBucket(new string[0], new Dictionary<string, string>(), new Lookup(itemsByName, new PropertyDictionary<ProjectPropertyInstance>(), null), 0); _host.FindTask(null); _host.InitializeForBatch(talc, _bucket, null); _parametersSetOnTask = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); _outputsReadFromTask = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); }
/// <summary> /// Determine if a given type name is in the assembly or not. Return null if the type is not in the assembly /// </summary> internal LoadedType GetLoadedTypeByTypeName(string typeName) { ErrorUtilities.VerifyThrowArgumentNull(typeName, "typeName"); // Only one thread should be doing operations on this instance of the object at a time. lock (_lockObject) { Type type = null; // Maybe we've already cracked open this assembly before. Check to see if the typeName is in the list we don't look for partial matches here // this is an optimization. bool foundType = _typeNameToType.TryGetValue(typeName, out type); if (!foundType) { // We could still not find the type, lets try and resolve it by doing a get type. if ((_assemblyLoadInfo.AssemblyName != null) && (typeName.Length > 0)) { try { // try to load the type using its assembly qualified name type = Type.GetType(typeName + "," + _assemblyLoadInfo.AssemblyName, false /* don't throw on error */, true /* case-insensitive */); } catch (ArgumentException) { // Type.GetType() will throw this exception if the type name is invalid -- but we have no idea if it's the // type or the assembly name that's the problem -- so just ignore the exception, because we're going to // check the existence/validity of the assembly and type respectively, below anyway } // if we found the type, it means its assembly qualified name was also its fully qualified name if (type != null) { // if it's not the right type, bail out -- there's no point searching further since we already matched on the // fully qualified name if (!_isDesiredType(type, null)) { _typeNameToType.Add(typeName, null); return(null); } else { _typeNameToType.Add(typeName, type); } } } // We could not find the type based on the passed in type name, we now need to see if there is a type which // will match based on partially matching the typename. To do this partial matching we need to get the public types in the assembly if (type == null && !_haveScannedPublicTypes) { ScanAssemblyForPublicTypes(); _haveScannedPublicTypes = true; } // Could not find the type we need to look through the types in the assembly or in our cache. if (type == null) { foreach (KeyValuePair <string, Type> desiredTypeInAssembly in _publicTypeNameToType) { // if type matches partially on its name if (typeName.Length == 0 || TypeLoader.IsPartialTypeNameMatch(desiredTypeInAssembly.Key, typeName)) { type = desiredTypeInAssembly.Value; _typeNameToType.Add(typeName, type); break; } } } } if (type != null) { return(new LoadedType(type, _assemblyLoadInfo, _loadedAssembly)); } return(null); } }
/// <summary> /// This is responsible for invoking Execute on the Task /// Any method calling ExecuteTask must remember to call CleanupTask /// </summary> /// <remarks> /// We also allow the Task to have a reference to the BuildEngine by design /// at ITask.BuildEngine /// </remarks> /// <param name="oopTaskHostNode">The OutOfProcTaskHostNode as the BuildEngine</param> /// <param name="taskName">The name of the task to be executed</param> /// <param name="taskLocation">The path of the task binary</param> /// <param name="taskFile">The path to the project file in which the task invocation is located.</param> /// <param name="taskLine">The line in the project file where the task invocation is located.</param> /// <param name="taskColumn">The column in the project file where the task invocation is located.</param> /// <param name="appDomainSetup">The AppDomainSetup that we want to use to launch our AppDomainIsolated tasks</param> /// <param name="taskParams">Parameters that will be passed to the task when created</param> /// <returns>Task completion result showing success, failure or if there was a crash</returns> internal OutOfProcTaskHostTaskResult ExecuteTask ( IBuildEngine oopTaskHostNode, string taskName, string taskLocation, string taskFile, int taskLine, int taskColumn, AppDomainSetup appDomainSetup, IDictionary<string, TaskParameter> taskParams ) { _buildEngine = oopTaskHostNode; _taskName = taskName; _taskAppDomain = null; _wrappedTask = null; LoadedType taskType = null; try { TypeLoader typeLoader = new TypeLoader(new TypeFilter(TaskLoader.IsTaskClass)); taskType = typeLoader.Load(taskName, AssemblyLoadInfo.Create(null, taskLocation)); } 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 } ); } OutOfProcTaskHostTaskResult taskResult; if (taskType.HasSTAThreadAttribute()) { taskResult = InstantiateAndExecuteTaskInSTAThread(oopTaskHostNode, taskType, taskName, taskLocation, taskFile, taskLine, taskColumn, appDomainSetup, taskParams); } else { taskResult = InstantiateAndExecuteTask(oopTaskHostNode, taskType, taskName, taskLocation, taskFile, taskLine, taskColumn, appDomainSetup, taskParams); } return taskResult; }