private async void OnLibraryChanged(WatcherChangeTypes changeType, string oldPath, string newPath) { if (newPath != null && (!newPath.ToLowerInvariant().EndsWith(ShellLibraryItem.EXTENSION, StringComparison.Ordinal) || !File.Exists(newPath))) { System.Diagnostics.Debug.WriteLine($"Ignored library event: {changeType}, {oldPath} -> {newPath}"); return; } System.Diagnostics.Debug.WriteLine($"Library event: {changeType}, {oldPath} -> {newPath}"); if (connection?.IsConnected ?? false) { var response = new ValueSet { { "Library", newPath ?? oldPath } }; switch (changeType) { case WatcherChangeTypes.Deleted: case WatcherChangeTypes.Renamed: response["OldPath"] = oldPath; break; default: break; } if (!changeType.HasFlag(WatcherChangeTypes.Deleted)) { var library = new ShellLibrary2(Shell32.ShellUtil.GetShellItemForPath(newPath), true); if (library == null) { Program.Logger.Warn($"Failed to open library after {changeType}: {newPath}"); return; } response["Item"] = JsonConvert.SerializeObject(ShellFolderExtensions.GetShellLibraryItem(library, newPath)); library.Dispose(); } // Send message to UWP app to refresh items await Win32API.SendMessageAsync(connection, response); } }
private async Task HandleShellLibraryMessage(Dictionary <string, object> message) { switch ((string)message["action"]) { case "Enumerate": // Read library information and send response to UWP var enumerateResponse = await Win32API.StartSTATask(() => { var response = new ValueSet(); try { var libraryItems = new List <ShellLibraryItem>(); // https://docs.microsoft.com/en-us/windows/win32/search/-search-win7-development-scenarios#library-descriptions var libFiles = Directory.EnumerateFiles(ShellLibraryItem.LibrariesPath, "*" + ShellLibraryItem.EXTENSION); foreach (var libFile in libFiles) { using var shellItem = new ShellLibrary2(Shell32.ShellUtil.GetShellItemForPath(libFile), true); if (shellItem is ShellLibrary2 library) { libraryItems.Add(ShellFolderExtensions.GetShellLibraryItem(library, libFile)); } } response.Add("Enumerate", JsonConvert.SerializeObject(libraryItems)); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, enumerateResponse, message.Get("RequestID", (string)null)); break; case "Create": // Try create new library with the specified name and send response to UWP var createResponse = await Win32API.StartSTATask(() => { var response = new ValueSet(); try { using var library = new ShellLibrary2((string)message["library"], Shell32.KNOWNFOLDERID.FOLDERID_Libraries, false); library.Folders.Add(ShellItem.Open(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))); // Add default folder so it's not empty library.Commit(); library.Reload(); response.Add("Create", JsonConvert.SerializeObject(ShellFolderExtensions.GetShellLibraryItem(library, library.GetDisplayName(ShellItemDisplayString.DesktopAbsoluteParsing)))); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, createResponse, message.Get("RequestID", (string)null)); break; case "Update": // Update details of the specified library and send response to UWP var updateResponse = await Win32API.StartSTATask(() => { var response = new ValueSet(); try { var folders = message.ContainsKey("folders") ? JsonConvert.DeserializeObject <string[]>((string)message["folders"]) : null; var defaultSaveFolder = message.Get("defaultSaveFolder", (string)null); var isPinned = message.Get("isPinned", (bool?)null); bool updated = false; var libPath = (string)message["library"]; using var library = new ShellLibrary2(Shell32.ShellUtil.GetShellItemForPath(libPath), false); if (folders != null) { if (folders.Length > 0) { var foldersToRemove = library.Folders.Where(f => !folders.Any(folderPath => string.Equals(folderPath, f.FileSystemPath, StringComparison.OrdinalIgnoreCase))); foreach (var toRemove in foldersToRemove) { library.Folders.Remove(toRemove); updated = true; } var foldersToAdd = folders.Distinct(StringComparer.OrdinalIgnoreCase) .Where(folderPath => !library.Folders.Any(f => string.Equals(folderPath, f.FileSystemPath, StringComparison.OrdinalIgnoreCase))) .Select(ShellItem.Open); foreach (var toAdd in foldersToAdd) { library.Folders.Add(toAdd); updated = true; } foreach (var toAdd in foldersToAdd) { toAdd.Dispose(); } } } if (defaultSaveFolder != null) { library.DefaultSaveFolder = ShellItem.Open(defaultSaveFolder); updated = true; } if (isPinned != null) { library.PinnedToNavigationPane = isPinned == true; updated = true; } if (updated) { library.Commit(); library.Reload(); // Reload folders list response.Add("Update", JsonConvert.SerializeObject(ShellFolderExtensions.GetShellLibraryItem(library, libPath))); } } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, updateResponse, message.Get("RequestID", (string)null)); break; } }