/// <summary> /// Traverses the specified base directory including all sub-directories, /// generating a list of assemblies that can be scanned, a list of /// skipped files, and a list of errors that occurred while scanning. /// Scanned files may be skipped when they're not a .NET assembly. /// </summary> public AssemblyScannerResults GetScannableAssemblies() { var results = new AssemblyScannerResults(); if (IncludeAppDomainAssemblies) { List <Assembly> matching_app_domain_assemblies = MatchingAssembliesFromAppDomain(); foreach (var assembly in matching_app_domain_assemblies) { ScanAssembly(AssemblyPath(assembly), results); } } IEnumerable <FileInfo> assembly_files = ScanDirectoryForAssemblyFiles(); foreach (var assembly_file in assembly_files) { ScanAssembly(assembly_file.FullName, results); } results.RemoveDuplicates(); return(results); }
void ScanAssembly(string assembly_path, AssemblyScannerResults results) { Assembly assembly; if (!IsIncluded(Path.GetFileNameWithoutExtension(assembly_path))) { var skipped_file = new SkippedFile(assembly_path, "File was explicitly excluded from scanning."); results.SkippedFiles.Add(skipped_file); return; } var compilation_mode = Image.GetCompilationMode(assembly_path); if (compilation_mode == Image.CompilationMode.NativeOrInvalid) { var skipped_file = new SkippedFile(assembly_path, "File is not a .NET assembly."); results.SkippedFiles.Add(skipped_file); return; } if (!Environment.Is64BitProcess && compilation_mode == Image.CompilationMode.CLRx64) { var skipped_file = new SkippedFile(assembly_path, "x64 .NET assembly can't be loaded by a 32Bit process."); results.SkippedFiles.Add(skipped_file); return; } try { if (IsRuntimeAssembly(assembly_path)) { var skipped_file = new SkippedFile(assembly_path, "Assembly .net runtime assembly."); results.SkippedFiles.Add(skipped_file); return; } assembly = Assembly.LoadFrom(assembly_path); if (results.Assemblies.Contains(assembly)) { return; } } catch (BadImageFormatException ex) { assembly = null; results.ErrorsThrownDuringScanning = true; if (ThrowExceptions) { var error_message = String.Format( "Could not load '{0}'. Consider excluding that assembly from the scanning.", assembly_path); throw new Exception(error_message, ex); } } if (assembly == null) { return; } try { //will throw if assembly cannot be loaded results.Types.AddRange(assembly.GetTypes().Where(IsAllowedType)); } catch (ReflectionTypeLoadException e) { results.ErrorsThrownDuringScanning = true; var error_message = FormatReflectionTypeLoadException(assembly_path, e); if (ThrowExceptions) { throw new Exception(error_message); } MustLogger.ForCurrentProcess.Warn(error_message); results.Types.AddRange(e.Types.Where(IsAllowedType)); } results.Assemblies.Add(assembly); }