(); if (Directory.Exists(plugins)) { foreach (var plugin in Directory.GetDirectories(plugins)) { foreach (var file in Directory.GetFiles(plugin, "*", SearchOption.AllDirectories)) { var relative = file.Substring(plugin.TrimEnd(Path.DirectorySeparatorChar).Length + 1); // Plugin settings are owned by the plugin even when identical to host settings. if (Path.GetFileName(file).StartsWith("appsettings", StringComparison.OrdinalIgnoreCase) && string.Equals(Path.GetExtension(file), ".json", StringComparison.OrdinalIgnoreCase)) continue; var shared = Path.GetFullPath(Path.Combine(host, relative)); // Only compare files below the host, outside its plugin subtree. if (!shared.StartsWith(host.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) || shared.StartsWith(plugins + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) || !File.Exists(shared) || new FileInfo(file).Length != new FileInfo(shared).Length) continue; using (var hash = SHA256.Create()) using (var source = File.OpenRead(file)) using (var target = File.OpenRead(shared)) { if (Convert.ToBase64String(hash.ComputeHash(source)) == Convert.ToBase64String(hash.ComputeHash(target))) duplicates.Add(new Microsoft.Build.Utilities.TaskItem(file)); } } } } Duplicates = duplicates.ToArray(); ]]>