public string SaveSnapshot() { try { Log.WriteLine($"SaveSnapshot"); Dictionary <uint, byte[]> clipboard = Win32.Clipboard.GetClipboard(); if (clipboard?.Any() == true) { string snapshotDir = Path.Combine(Globals.DataDir, NextItemId()); Directory.CreateDirectory(snapshotDir); var bytesHash = new BytesHash(); foreach (uint item in clipboard.Keys.OrderBy(x => x)) { string formatFile = Path.Combine(snapshotDir, $"{item:X8}.{item.ToFormatName()}.cbd"); var array = new byte[0]; try { array = clipboard[item]; } catch { } if (array.Any()) { if (uniqunessFormats.ContainsKey(item)) { bytesHash.Add(array); } if (Config.EncryptData && Config.CacheEncryptDataMinSize < array.Length) { Cache[formatFile] = array; } WritePrivateData(formatFile, array); } } string shapshotHashFile = Path.Combine(snapshotDir, bytesHash + ".hash"); File.WriteAllText(shapshotHashFile, ""); return(shapshotHashFile); } } catch (Clipboard.LastSessionErrorDetectedException ex) { if (Environment.GetEnvironmentVariable("MULTICLIP_SHOW_ERRORS") != null) { var newThread = new Thread(() => { try { Thread.Sleep(1000); Clipboard.SetText($"MultiClip Error: {ex.Message}"); } catch { } }); newThread.IsBackground = true; newThread.SetApartmentState(ApartmentState.STA); newThread.Start(); } } catch { } return(null); }
public static void Purge(bool showOnly = false) { foreach (var dir in Directory.GetDirectories(Globals.DataDir, "???????????????").OrderBy(x => x)) { if (!Directory.GetFiles(dir, "*.hash").Any()) { Console.WriteLine("Deleting hash-less data dir: " + dir); if (!showOnly) { dir.TryDeleteDir(); } } } var titles = new Dictionary <string, string>(); foreach (var file in Directory.GetFiles(Globals.DataDir, "*.hash", SearchOption.AllDirectories).OrderByDescending(x => x)) { var snapshot_dir = Path.GetDirectoryName(file); var title = "<binary>"; var hash = new BytesHash(); foreach (var data_file in Directory.GetFiles(snapshot_dir, "*.cbd").OrderBy(x => x)) { // For example: 00000001.Text.cbd or 0000000D.UnicodeText.cbd string format = Path.GetFileNameWithoutExtension(data_file); if (uniqunessFormats.ContainsValue(format)) { var bytes = new byte[0]; try { // File.ReadAllBytes(data_file) will not work because even the same data encrypted // twice (e.g. to different location) will produce different data. Thus need to decrypt it first bytes = ReadPrivateData(data_file); if (showOnly && true) { if (format == "0000000D.UnicodeText") { title = bytes.ToUnicodeTitle(20); Console.WriteLine($"{Path.GetFileName(snapshot_dir)}: {title}"); } } } catch { } hash.Add(bytes); } } titles[snapshot_dir] = title; foreach (var old_text_ash in Directory.GetFiles(snapshot_dir, "*.text_hash")) { File.Delete(old_text_ash); } string crcFile = Path.Combine(snapshot_dir, hash + ".text_hash"); File.WriteAllText(crcFile, ""); } var duplicates = Directory.GetFiles(Globals.DataDir, "*.text_hash", SearchOption.AllDirectories) .GroupBy(Path.GetFileName) .Select(x => new { Hash = x.Key, Files = x.ToArray() }) .ForEach(x => { Debug.WriteLine(""); Debug.WriteLine($"{x.Hash}"); var snapshot = Path.GetDirectoryName(x.Files.First()); if (titles.ContainsKey(snapshot)) { Debug.WriteLine($"{titles[snapshot]}"); } foreach (var item in x.Files) { Debug.WriteLine(" " + item); } }); var dirs_to_purge = duplicates.Where(x => x.Files.Count() > 1).ToArray(); Debug.WriteLine(">>> Duplicates: " + dirs_to_purge.Length); foreach (var item in dirs_to_purge) { item.Files.Skip(1).ForEach(x => { var dir = Path.GetDirectoryName(x); Console.WriteLine("Deleting " + dir); if (titles.ContainsKey(dir)) { Debug.WriteLine(titles[dir]); } if (!showOnly) { dir.TryDeleteDir(); } }); } }