/* * void LinkAllDuplicates(List<DuplicateFile> duplicates) { * int last = 0; * for (long n = 0; n < duplicates.Count; n++) { * LinkDuplicates(duplicates[(int)n]); * pbStatus.Value = n; * if ((n * 100) / duplicates.Count > last * 5) { * last++; * Task.Delay(100); * } * } * } */ /// <summary> /// Create a <see cref="Expander"/> containing this <see cref="DuplicateFile"/> /// </summary> /// <param name="df"><see cref="DuplicateFile"/> to display</param> /// <param name="bg">Background color of the created <see cref="Expander"/></param> /// <returns>A expander visualizing the Duplicate</returns> Expander CreateEntry(DuplicateFile df, SolidColorBrush bg) { hashedFiles.TryGetValue(df.instances[0], out var myhash); var exp = new Expander() { Header = df.filename + "\t(" + (myhash == null ? "NULL" : Convert.ToBase64String(myhash)) + ")", Background = bg, BorderBrush = null }; var mysp = new StackPanel(); foreach (var path in df.instances) { mysp.Children.Add( new TextBox() { BorderBrush = null, Background = null, IsReadOnly = true, IsReadOnlyCaretVisible = false, Text = String.IsNullOrEmpty(path) ? "NULL" : path }); } exp.Content = mysp; return(exp); }
/// <summary> /// Do the linking of one file /// Ensures that duplicate link limits are not exceeded /// </summary> /// <param name="file">The DuplicateFile to link into one</param> static void LinkDuplicates(DuplicateFile file) { file.instances.Sort(); var newExtension = ".DVSLINKER.BAK"; string prefix = "\\\\?\\"; // @"\?"; var orig = prefix + pathStorage[file.instances[0]]; uint links = Util.GetLinks(file); for (int n = 1; n < file.instances.Count; n++, links++) { var curr = pathStorage[file.instances[n]]; if (links >= 1023) { orig = prefix + file.instances[n]; links = Util.GetLinks(curr) - 1; //for loops adds 1 back on } else { var backup = file.instances[n] + newExtension; try { if (File.Exists(backup)) { File.Delete(backup); } File.Copy(curr, backup); //backup File.Delete(curr); } catch { if (!File.Exists(curr)) { if (File.Exists(backup)) { File.Copy(backup, curr); File.Delete(backup); } } continue; } var path = prefix + file.instances[n]; if (!Syscall.CreateHardLink(path, orig, IntPtr.Zero)) { uint error = Syscall.GetLastError(); //Marshal.GetLastWin32Error(); Debug.WriteLine("ERROR: " + error); File.Copy(backup, curr); //restore backup File.Delete(backup); } else { File.Delete(backup); //remove backup because HardLink worked } } } }
/// <summary> /// Analyze all normal files and find duplicate filenames /// </summary> /// <param name="transfer"> /// Tuple<List< <see cref="DuplicateFile"/>>, List< <see cref="NormalFile"/>>> /// reference for searching and output /// </param> void FindDuplicates(object transfer) { position = 0; var trans = (Tuple <List <DuplicateFile>, List <NormalFile> >)transfer; var filePaths = trans.Item2; for (var i = 0; i < filePaths.Count; i++, position++) { var work = new DuplicateFile(filePaths[i]); for (var n = i + 1; n < filePaths.Count; n++) { if (work.filename == filePaths[n].filename) { work.instances.Add(filePaths[n].fullpath); } } if (work.instances.Count > 1) { trans.Item1.Add(work); } } running = 0; }
/// <summary> /// Gets the number of HardLinks of the first <see cref="DuplicateFile.instances"/> in <paramref name="df"/> /// </summary> /// <param name="df">DuplicateFile to analyze</param> /// <returns></returns> static uint GetLinks(DuplicateFile df) => GetLinks(df.instances[0]);
/// <summary> /// Gets the number of HardLinks of the first <see cref="DuplicateFile.instances"/> in <paramref name="df"/> /// </summary> /// <param name="df">DuplicateFile to analyze</param> /// <returns></returns> public static uint GetLinks(DuplicateFile df) => GetLinks(MainWindow.pathStorage[df.instances[0]]);