/// <summary> /// Creates an instance of this class for the given type. /// </summary> /// <owner>SumedhK</owner> /// <param name="type"></param> /// <param name="assembly"></param> internal LoadedType(Type type, AssemblyLoadInfo assembly) { ErrorUtilities.VerifyThrow(type != null, "We must have the type."); ErrorUtilities.VerifyThrow(assembly != null, "We must have the assembly the type was loaded from."); this.type = type; this.assembly = assembly; }
/// <summary> /// Determines if two AssemblyLoadInfos are effectively the same. /// </summary> /// <returns></returns> /// <owner>RGoel</owner> public override bool Equals(Object obj) { if (obj == null) { return(false); } AssemblyLoadInfo otherAssemblyInfo = obj as AssemblyLoadInfo; if (otherAssemblyInfo == null) { return(false); } return((this.AssemblyName == otherAssemblyInfo.AssemblyName) && (this.AssemblyFile == otherAssemblyInfo.AssemblyFile)); }
/// <summary> /// Loads the specified type if it exists in the given assembly. If the type name is fully qualified, then a match (if /// any) is unambiguous; otherwise, if there are multiple types with the same name in different namespaces, the first type /// found will be returned. /// </summary> /// <remarks>This method throws exceptions -- it is the responsibility of the caller to handle them.</remarks> /// <owner>SumedhK</owner> /// <param name="typeName">Can be empty string.</param> /// <param name="assembly"></param> /// <returns>The loaded type, or null if the type was not found.</returns> internal LoadedType Load ( string typeName, AssemblyLoadInfo assembly ) { Type type = null; // Maybe we've already cracked open this assembly before. If so, just grab the list // of public desired types that we found last time. List<Type> desiredTypesInAssembly = null; cacheOfAllDesiredTypesInAnAssembly.TryGetValue(assembly, out desiredTypesInAssembly); // If we have the assembly name (strong or weak), and we haven't cracked this assembly open // before to discover all the public desired types. if ((assembly.AssemblyName != null) && (typeName.Length > 0) && (desiredTypesInAssembly == null)) { try { // try to load the type using its assembly qualified name type = Type.GetType(typeName + "," + assembly.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)) { return null; } } // if the type name was not fully qualified, or if we only have the assembly file/path else { if (desiredTypesInAssembly == null) { // we need to search the assembly for the type... Assembly loadedAssembly; try { if (assembly.AssemblyName != null) { loadedAssembly = Assembly.Load(assembly.AssemblyName); } else { loadedAssembly = Assembly.UnsafeLoadFrom(assembly.AssemblyFile); } } // Assembly.Load() and Assembly.LoadFrom() will throw an ArgumentException if the assembly name is invalid catch (ArgumentException e) { // convert to a FileNotFoundException because it's more meaningful // NOTE: don't use ErrorUtilities.VerifyThrowFileExists() here because that will hit the disk again throw new FileNotFoundException(null, assembly.ToString(), e); } // only look at public types Type[] allPublicTypesInAssembly = loadedAssembly.GetExportedTypes(); desiredTypesInAssembly = new List<Type>(); foreach (Type publicType in allPublicTypesInAssembly) { if (isDesiredType(publicType, null)) { desiredTypesInAssembly.Add(publicType); } } // Save the list of desired types into our cache, so that we don't have to crack it // open again. cacheOfAllDesiredTypesInAnAssembly[assembly] = desiredTypesInAssembly; } foreach (Type desiredTypeInAssembly in desiredTypesInAssembly) { // if type matches partially on its name if ((typeName.Length == 0) || IsPartialTypeNameMatch(desiredTypeInAssembly.FullName, typeName)) { type = desiredTypeInAssembly; break; } } } if (type != null) { return new LoadedType(type, assembly); } return null; }
/// <summary> /// Loads the specified type if it exists in the given assembly. If the type name is fully qualified, then a match (if /// any) is unambiguous; otherwise, if there are multiple types with the same name in different namespaces, the first type /// found will be returned. /// </summary> /// <remarks>This method throws exceptions -- it is the responsibility of the caller to handle them.</remarks> /// <owner>SumedhK</owner> /// <param name="typeName">Can be empty string.</param> /// <param name="assembly"></param> /// <returns>The loaded type, or null if the type was not found.</returns> internal LoadedType Load ( string typeName, AssemblyLoadInfo assembly ) { Type type = null; // Maybe we've already cracked open this assembly before. If so, just grab the list // of public desired types that we found last time. List <Type> desiredTypesInAssembly = null; cacheOfAllDesiredTypesInAnAssembly.TryGetValue(assembly, out desiredTypesInAssembly); // If we have the assembly name (strong or weak), and we haven't cracked this assembly open // before to discover all the public desired types. if ((assembly.AssemblyName != null) && (typeName.Length > 0) && (desiredTypesInAssembly == null)) { try { // try to load the type using its assembly qualified name type = Type.GetType(typeName + "," + assembly.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)) { return(null); } } // if the type name was not fully qualified, or if we only have the assembly file/path else { if (desiredTypesInAssembly == null) { // we need to search the assembly for the type... Assembly loadedAssembly; try { if (assembly.AssemblyName != null) { loadedAssembly = Assembly.Load(assembly.AssemblyName); } else { loadedAssembly = Assembly.UnsafeLoadFrom(assembly.AssemblyFile); } } // Assembly.Load() and Assembly.LoadFrom() will throw an ArgumentException if the assembly name is invalid catch (ArgumentException e) { // convert to a FileNotFoundException because it's more meaningful // NOTE: don't use ErrorUtilities.VerifyThrowFileExists() here because that will hit the disk again throw new FileNotFoundException(null, assembly.ToString(), e); } // only look at public types Type[] allPublicTypesInAssembly = loadedAssembly.GetExportedTypes(); desiredTypesInAssembly = new List <Type>(); foreach (Type publicType in allPublicTypesInAssembly) { if (isDesiredType(publicType, null)) { desiredTypesInAssembly.Add(publicType); } } // Save the list of desired types into our cache, so that we don't have to crack it // open again. cacheOfAllDesiredTypesInAnAssembly[assembly] = desiredTypesInAssembly; } foreach (Type desiredTypeInAssembly in desiredTypesInAssembly) { // if type matches partially on its name if ((typeName.Length == 0) || IsPartialTypeNameMatch(desiredTypeInAssembly.FullName, typeName)) { type = desiredTypeInAssembly; break; } } } if (type != null) { return(new LoadedType(type, assembly)); } return(null); }
public UsingTaskInfo(string taskName, string assemblyName, string assemblyFile) { TaskName = taskName; AssemblyInfo = new AssemblyLoadInfo(assemblyName, assemblyFile); }
internal void CreateFromStream(BinaryReader reader) { #region LoggerClassName if (reader.ReadByte() ==0) { loggerClassName = null; } else { loggerClassName = reader.ReadString(); } #endregion #region LoggerSwitchParameters if (reader.ReadByte() == 0) { loggerSwitchParameters = null; } else { loggerSwitchParameters = reader.ReadString(); } #endregion #region LoggerAssembly if (reader.ReadByte() == 0) { loggerAssembly = null; } else { string assemblyName = null; string assemblyFile = null; if (reader.ReadByte() != 0) { assemblyFile = reader.ReadString(); } if (reader.ReadByte() != 0) { assemblyName = reader.ReadString(); } loggerAssembly = new AssemblyLoadInfo(assemblyName, assemblyFile); } #endregion verbosity = (LoggerVerbosity)reader.ReadInt32(); loggerId = reader.ReadInt32(); }
/// <summary> /// Converts the path to the logger assembly to a full path /// </summary> internal void ConvertPathsToFullPaths() { if (loggerAssembly.AssemblyFile != null) { loggerAssembly = new AssemblyLoadInfo(loggerAssembly.AssemblyName, Path.GetFullPath(loggerAssembly.AssemblyFile)); } }
/// <summary> /// Reads the given <UsingTask> tag and saves the task information specified in it. /// </summary> /// <param name="usingTask"></param> /// <param name="expander"></param> /// <param name="loggingServices"></param> /// <param name="buildEventContext"></param> public void RegisterTask(UsingTask usingTask, Expander expander, EngineLoggingServices loggingServices, BuildEventContext buildEventContext) { if ( // if the <UsingTask> tag doesn't have a condition on it (usingTask.Condition == null) || // or if the condition holds Utilities.EvaluateCondition(usingTask.Condition, usingTask.ConditionAttribute, expander, null, ParserOptions.AllowProperties | ParserOptions.AllowItemLists, loggingServices, buildEventContext) ) { // Lazily allocate the hashtables if they are needed if (registeredTasks == null) { cachedTaskClassesWithExactMatch = new Hashtable(StringComparer.OrdinalIgnoreCase); cachedTaskClassesWithFuzzyMatch = new Hashtable(StringComparer.OrdinalIgnoreCase); registeredTasks = new Hashtable(StringComparer.OrdinalIgnoreCase); } string assemblyName = null; string assemblyFile = null; if (usingTask.AssemblyName != null) { // expand out all embedded properties and items in the assembly name assemblyName = expander.ExpandAllIntoString(usingTask.AssemblyName, usingTask.AssemblyNameAttribute); ProjectErrorUtilities.VerifyThrowInvalidProject(assemblyName.Length > 0, usingTask.AssemblyNameAttribute, "InvalidEvaluatedAttributeValue", assemblyName, usingTask.AssemblyName, XMakeAttributes.assemblyName, XMakeElements.usingTask); } else { // expand out all embedded properties and items in the assembly file/path assemblyFile = expander.ExpandAllIntoString(usingTask.AssemblyFile, usingTask.AssemblyFileAttribute); ProjectErrorUtilities.VerifyThrowInvalidProject(assemblyFile.Length > 0, usingTask.AssemblyFileAttribute, "InvalidEvaluatedAttributeValue", assemblyFile, usingTask.AssemblyFile, XMakeAttributes.assemblyFile, XMakeElements.usingTask); // figure out the directory of the project in which this <UsingTask> node was defined string projectFile = XmlUtilities.GetXmlNodeFile(usingTask.TaskNameAttribute.OwnerElement, String.Empty); string projectDir = (projectFile.Length > 0) ? Path.GetDirectoryName(projectFile) : String.Empty; // ensure the assembly file/path is relative to the project in which this <UsingTask> node was defined -- we // don't want paths from imported projects being interpreted relative to the main project file try { assemblyFile = Path.Combine(projectDir, assemblyFile); } catch (ArgumentException ex) { // Invalid chars in AssemblyFile path ProjectErrorUtilities.VerifyThrowInvalidProject(false, usingTask.AssemblyFileAttribute, "InvalidAttributeValueWithException", assemblyFile, XMakeAttributes.assemblyFile, XMakeElements.usingTask, ex.Message); } } AssemblyLoadInfo taskAssembly = new AssemblyLoadInfo(assemblyName, assemblyFile); // expand out all embedded properties and items string taskName = expander.ExpandAllIntoString(usingTask.TaskName, usingTask.TaskNameAttribute); ProjectErrorUtilities.VerifyThrowInvalidProject(taskName.Length > 0, usingTask.TaskNameAttribute, "InvalidEvaluatedAttributeValue", taskName, usingTask.TaskName, XMakeAttributes.taskName, XMakeElements.usingTask); // since more than one task can have the same name, we want to keep track of all assemblies that are declared to // contain tasks with a given name... ArrayList taskAssemblies = (ArrayList)registeredTasks[taskName]; if (taskAssemblies == null) { taskAssemblies = new ArrayList(); registeredTasks[taskName] = taskAssemblies; } taskAssemblies.Add(taskAssembly); } }