void VisitFolderInternal(IProgressStatus monitor, string path, string domain, bool recursive) { // Avoid folders including each other if (!visitedFolders.Add(path) || ScanContext.IgnorePath(path)) { return; } OnVisitFolder(monitor, path, domain, recursive); }
protected virtual void OnVisitFolder(IProgressStatus monitor, string path, string domain, bool recursive) { if (!FileSystem.DirectoryExists(path)) { return; } var files = FileSystem.GetFiles(path).ToArray(); // First of all scan .addins files, since they can contain exclude paths. // Only extract the information, don't follow directory inclusions yet List <AddinsEntry> addinsFileEntries = new List <AddinsEntry>(); foreach (string file in files) { if (Path.GetExtension(file).EndsWith(".addins", StringComparison.Ordinal)) { addinsFileEntries.AddRange(ParseAddinsFile(monitor, file, domain)); } } // Now look for .addin files. Addin files must be processed before // assemblies, because they may add files to the ignore list (i.e., assemblies // included in .addin files won't be scanned twice). foreach (string file in files) { if (!ScanContext.IgnorePath(file) && (file.EndsWith(".addin.xml", StringComparison.Ordinal) || file.EndsWith(".addin", StringComparison.Ordinal))) { OnVisitAddinManifestFile(monitor, file); } } // Now scan assemblies. They can also add files to the ignore list. foreach (string file in files) { if (!ScanContext.IgnorePath(file)) { string ext = Path.GetExtension(file).ToLower(); if (ext == ".dll" || ext == ".exe") { OnVisitAssemblyFile(monitor, file); } } } // Follow .addins file inclusions foreach (var entry in addinsFileEntries) { string dir = entry.Folder; if (!Path.IsPathRooted(dir)) { dir = Path.GetFullPath(Path.Combine(path, entry.Folder)); } VisitFolderInternal(monitor, dir, entry.Domain, entry.Recursive); } // Scan subfolders if (recursive) { foreach (string sd in FileSystem.GetDirectories(path)) { VisitFolderInternal(monitor, sd, domain, true); } } }