private async Task ParseNetworkDriveOperationAsync(PipeStream connection, Dictionary <string, object> message) { switch (message.Get("netdriveop", "")) { case "GetNetworkLocations": var networkLocations = await Win32API.StartSTATask(() => { var locations = new List <ShellLinkItem>(); using (var nethood = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_NetHood)) { foreach (var item in nethood) { if (item is ShellLink link) { locations.Add(ShellFolderExtensions.GetShellLinkItem(link)); } else { var linkPath = (string)item.Properties["System.Link.TargetParsingPath"]; if (linkPath != null) { var linkItem = ShellFolderExtensions.GetShellFileItem(item); locations.Add(new ShellLinkItem(linkItem) { TargetPath = linkPath }); } } } } return(locations); }); var response = new ValueSet { { "NetworkLocations", JsonConvert.SerializeObject(networkLocations) } }; await Win32API.SendMessageAsync(connection, response, message.Get("RequestID", (string)null)); break; case "OpenMapNetworkDriveDialog": var hwnd = (long)message["HWND"]; _ = NetworkDrivesAPI.OpenMapNetworkDriveDialog(hwnd); break; case "DisconnectNetworkDrive": var drivePath = (string)message["drive"]; _ = NetworkDrivesAPI.DisconnectNetworkDrive(drivePath); break; } }
public async Task ParseArgumentsAsync(PipeStream connection, Dictionary <string, object> message, string arguments) { switch (arguments) { case "Bitlocker": var bitlockerAction = (string)message["action"]; if (bitlockerAction == "Unlock") { var drive = (string)message["drive"]; var password = (string)message["password"]; Win32API.UnlockBitlockerDrive(drive, password); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Bitlocker", "Unlock" } }, message.Get("RequestID", (string)null)); } break; case "SetVolumeLabel": var driveName = (string)message["drivename"]; var newLabel = (string)message["newlabel"]; Win32API.SetVolumeLabel(driveName, newLabel); await Win32API.SendMessageAsync(connection, new ValueSet() { { "SetVolumeLabel", driveName } }, message.Get("RequestID", (string)null)); break; case "GetIconOverlay": var fileIconPath = (string)message["filePath"]; var thumbnailSize = (int)(long)message["thumbnailSize"]; var isOverlayOnly = (bool)message["isOverlayOnly"]; var(icon, overlay) = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath, thumbnailSize, true, isOverlayOnly)); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Icon", icon }, { "Overlay", overlay } }, message.Get("RequestID", (string)null)); break; case "GetIconWithoutOverlay": var fileIconPath2 = (string)message["filePath"]; var thumbnailSize2 = (int)(long)message["thumbnailSize"]; var icon2 = await Win32API.StartSTATask(() => Win32API.GetFileIconAndOverlay(fileIconPath2, thumbnailSize2, false)); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Icon", icon2.icon }, }, message.Get("RequestID", (string)null)); break; case "ShellItem": var itemPath = (string)message["item"]; var siAction = (string)message["action"]; var siResponseEnum = new ValueSet(); var item = await Win32API.StartSTATask(() => { using var shellItem = ShellFolderExtensions.GetShellItemFromPathOrPidl(itemPath); return(ShellFolderExtensions.GetShellFileItem(shellItem)); }); siResponseEnum.Add("Item", JsonConvert.SerializeObject(item)); await Win32API.SendMessageAsync(connection, siResponseEnum, message.Get("RequestID", (string)null)); break; case "ShellFolder": var folderPath = (string)message["folder"]; if (folderPath.StartsWith("::{", StringComparison.Ordinal)) { folderPath = $"shell:{folderPath}"; } var sfAction = (string)message["action"]; var fromIndex = (int)message.Get("from", 0L); var maxItems = (int)message.Get("count", (long)int.MaxValue); var sfResponseEnum = new ValueSet(); var(folder, folderContentsList) = await Win32API.StartSTATask(() => { var flc = new List <ShellFileItem>(); var folder = (ShellFileItem)null; try { using var shellFolder = ShellFolderExtensions.GetShellItemFromPathOrPidl(folderPath) as ShellFolder; folder = ShellFolderExtensions.GetShellFileItem(shellFolder); if ((controlPanel.PIDL.IsParentOf(shellFolder.PIDL, false) || controlPanelCategoryView.PIDL.IsParentOf(shellFolder.PIDL, false)) && !shellFolder.Any()) { // Return null to force open unsupported items in explorer // Only if inside control panel and folder appears empty return(null, flc); } if (sfAction == "Enumerate") { foreach (var folderItem in shellFolder.Skip(fromIndex).Take(maxItems)) { try { var shellFileItem = folderItem is ShellLink link ? ShellFolderExtensions.GetShellLinkItem(link) : ShellFolderExtensions.GetShellFileItem(folderItem); flc.Add(shellFileItem); } catch (FileNotFoundException) { // Happens if files are being deleted } finally { folderItem.Dispose(); } } } } catch { } return(folder, flc); }); sfResponseEnum.Add("Folder", JsonConvert.SerializeObject(folder)); sfResponseEnum.Add("Enumerate", JsonConvert.SerializeObject(folderContentsList, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects })); await Win32API.SendMessageAsync(connection, sfResponseEnum, message.Get("RequestID", (string)null)); break; case "GetFolderIconsFromDLL": var iconInfos = Win32API.ExtractIconsFromDLL((string)message["iconFile"]); await Win32API.SendMessageAsync(connection, new ValueSet() { { "IconInfos", JsonConvert.SerializeObject(iconInfos) }, }, message.Get("RequestID", (string)null)); break; case "SetCustomFolderIcon": await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", Win32API.SetCustomDirectoryIcon((string)message["folder"], (string)message["iconFile"], (int)message.Get("iconIndex", 0L)) }, }, message.Get("RequestID", (string)null)); break; case "GetSelectedIconsFromDLL": var selectedIconInfos = Win32API.ExtractSelectedIconsFromDLL((string)message["iconFile"], JsonConvert.DeserializeObject <List <int> >((string)message["iconIndexes"]), Convert.ToInt32(message["requestedIconSize"])); await Win32API.SendMessageAsync(connection, new ValueSet() { { "IconInfos", JsonConvert.SerializeObject(selectedIconInfos) }, }, message.Get("RequestID", (string)null)); break; case "SetAsDefaultExplorer": { var enable = (bool)message["Value"]; var destFolder = Path.Combine(ApplicationData.Current.LocalFolder.Path, "FilesOpenDialog"); Directory.CreateDirectory(destFolder); foreach (var file in Directory.GetFiles(Path.Combine(Package.Current.InstalledLocation.Path, "Files.FullTrust", "Assets", "FilesOpenDialog"))) { if (!SafetyExtensions.IgnoreExceptions(() => File.Copy(file, Path.Combine(destFolder, Path.GetFileName(file)), true), Program.Logger)) { // Error copying files DetectIsSetAsDefaultFileManager(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null)); return; } } var dataPath = Environment.ExpandEnvironmentVariables("%LocalAppData%\\Files"); if (enable) { if (!Win32API.RunPowershellCommand($"-command \"New-Item -Force -Path '{dataPath}' -ItemType Directory; Copy-Item -Filter *.* -Path '{destFolder}\\*' -Recurse -Force -Destination '{dataPath}'\"", false)) { // Error copying files DetectIsSetAsDefaultFileManager(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null)); return; } } else { Win32API.RunPowershellCommand($"-command \"Remove-Item -Path '{dataPath}' -Recurse -Force\"", false); } try { using var regProcess = Process.Start(new ProcessStartInfo("regedit.exe", @$ "/s " "{Path.Combine(destFolder, enable ? " SetFilesAsDefault.reg " : " UnsetFilesAsDefault.reg ")}" "") { UseShellExecute = true, Verb = "runas" }); regProcess.WaitForExit(); DetectIsSetAsDefaultFileManager(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", true } }, message.Get("RequestID", (string)null)); } catch { // Canceled UAC DetectIsSetAsDefaultFileManager(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", false } }, message.Get("RequestID", (string)null)); } }
private async Task HandleShellRecentItemsMessage(Dictionary <string, object> message) { var action = (string)message["action"]; var response = new ValueSet(); switch (action) { // enumerate `\Windows\Recent` for recent folders // note: files are enumerated using (Win32MessageHandler: "ShellFolder") in RecentItemsManager case "EnumerateFolders": var enumerateFoldersResponse = await Win32API.StartSTATask(() => { try { var shellLinkItems = new List <ShellLinkItem>(); var excludeMask = FileAttributes.Hidden; var linkFilePaths = Directory.EnumerateFiles(RecentItemsPath).Where(f => (new FileInfo(f).Attributes & excludeMask) == 0); foreach (var linkFilePath in linkFilePaths) { using var link = new ShellLink(linkFilePath, LinkResolution.NoUIWithMsgPump, null, TimeSpan.FromMilliseconds(100)); try { if (!string.IsNullOrEmpty(link.TargetPath) && link.Target.IsFolder) { var shellLinkItem = ShellFolderExtensions.GetShellLinkItem(link); shellLinkItems.Add(shellLinkItem); } } catch (FileNotFoundException) { // occurs when shortcut or shortcut target is deleted and accessed (link.Target) // consequently, we shouldn't include the item as a recent item } } response.Add("EnumerateFolders", JsonConvert.SerializeObject(shellLinkItems)); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, enumerateFoldersResponse, message.Get("RequestID", (string)null)); break; case "Add": var addResponse = await Win32API.StartSTATask(() => { try { var path = (string)message["Path"]; Shell32.SHAddToRecentDocs(Shell32.SHARD.SHARD_PATHW, path); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, addResponse, message.Get("RequestID", (string)null)); break; case "Clear": var clearResponse = await Win32API.StartSTATask(() => { try { Shell32.SHAddToRecentDocs(Shell32.SHARD.SHARD_PIDL, (string)null); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, clearResponse, message.Get("RequestID", (string)null)); break; // invoke 'remove' verb on the file to remove it from Quick Access // note: for folders, we need to use the verb 'unpinfromhome' or 'removefromhome' case "UnpinFile": var unpinFileResponse = await Win32API.StartSTATask(() => { try { var path = (string)message["Path"]; var command = $"-command \"((New-Object -ComObject Shell.Application).Namespace('shell:{QuickAccessGuid}\').Items() " + $"| Where-Object {{ $_.Path -eq '{path}' }}).InvokeVerb('remove')\""; bool success = Win32API.RunPowershellCommand(command, false); response.Add("UnpinFile", path); response.Add("Success", success); } catch (Exception e) { Program.Logger.Warn(e); } return(response); }); await Win32API.SendMessageAsync(connection, unpinFileResponse, message.Get("RequestID", (string)null)); break; } }