public static Encoding DetectFileEncoding(ZipFile zipFile) { long readEntries = 0; Ude.CharsetDetector cdet = new(); foreach (var entry in zipFile.OfType <ZipEntry>()) { readEntries++; if (entry.IsUnicodeText) { return(Encoding.UTF8); } var guessedEncoding = SafetyExtensions.IgnoreExceptions(() => { var rawBytes = Encoding.GetEncoding(Constants.Filesystem.ExtendedAsciiCodePage).GetBytes(entry.Name); cdet.Feed(rawBytes, 0, rawBytes.Length); cdet.DataEnd(); if (cdet.Charset != null && cdet.Confidence >= 0.9 && (readEntries >= Math.Min(zipFile.Count, 50))) { return(Encoding.GetEncoding(cdet.Charset)); } return(null); }); if (guessedEncoding != null) { return(guessedEncoding); } } return(Encoding.UTF8); }
private static T TryGetProperty <T>(this ShellItemPropertyStore sip, Ole32.PROPERTYKEY key) { T value = default; SafetyExtensions.IgnoreExceptions(() => sip.TryGetValue <T>(key, out value)); return(value); }
private async void RecycleBinWatcher_Changed(object sender, FileSystemEventArgs e) { System.Diagnostics.Debug.WriteLine($"Recycle bin event: {e.ChangeType}, {e.FullPath}"); if (e.Name.StartsWith("$I", StringComparison.Ordinal)) { // Recycle bin also stores a file starting with $I for each item return; } if (connection?.IsConnected ?? false) { var response = new ValueSet() { { "FileSystem", @"Shell:RecycleBinFolder" }, { "Path", e.FullPath }, { "Type", e.ChangeType.ToString() } }; if (e.ChangeType == WatcherChangeTypes.Created) { using var folderItem = SafetyExtensions.IgnoreExceptions(() => new ShellItem(e.FullPath)); if (folderItem == null) { return; } var shellFileItem = ShellFolderExtensions.GetShellFileItem(folderItem); response["Item"] = JsonConvert.SerializeObject(shellFileItem); } // Send message to UWP app to refresh items await Win32API.SendMessageAsync(connection, response); } }
private static Task <IEnumerable <ICloudProvider> > DetectGenericCloudDrive() { var results = new List <ICloudProvider>(); using var clsidKey = Registry.ClassesRoot.OpenSubKey(@"CLSID"); using var namespaceKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace"); foreach (var subKeyName in namespaceKey.GetSubKeyNames()) { using var clsidSubKey = SafetyExtensions.IgnoreExceptions(() => clsidKey.OpenSubKey(subKeyName)); if (clsidSubKey is not null && (int?)clsidSubKey.GetValue("System.IsPinnedToNameSpaceTree") is 1) { using var namespaceSubKey = namespaceKey.OpenSubKey(subKeyName); var driveType = (string)namespaceSubKey?.GetValue(string.Empty); if (driveType is null) { continue; } //Nextcloud specific var appName = (string)namespaceSubKey?.GetValue("ApplicationName"); if (!string.IsNullOrEmpty(appName) && appName == "Nextcloud") { driveType = appName; } using var bagKey = clsidSubKey.OpenSubKey(@"Instance\InitPropertyBag"); var syncedFolder = (string)bagKey?.GetValue("TargetFolderPath"); if (syncedFolder is null) { continue; } // Also works for OneDrive, Box, iCloudDrive, Dropbox CloudProviders?driveID = driveType switch { "MEGA" => CloudProviders.Mega, "Amazon Drive" => CloudProviders.AmazonDrive, "Nextcloud" => CloudProviders.Nextcloud, "Jottacloud" => CloudProviders.Jottacloud, _ => null, }; if (driveID is null) { continue; } string nextCloudValue = (string)namespaceSubKey?.GetValue(string.Empty); results.Add(new CloudProvider(driveID.Value) { Name = driveID switch { CloudProviders.Mega => $"MEGA ({Path.GetFileName(syncedFolder.TrimEnd('\\'))})", CloudProviders.AmazonDrive => $"Amazon Drive", CloudProviders.Nextcloud => !string.IsNullOrEmpty(nextCloudValue) ? nextCloudValue : "Nextcloud", CloudProviders.Jottacloud => $"Jottacloud", _ => null },
public void CopyVersionInfo() { SafetyExtensions.IgnoreExceptions(() => { DataPackage dataPackage = new DataPackage(); dataPackage.RequestedOperation = DataPackageOperation.Copy; dataPackage.SetText(Version + "\nOS Version: " + SystemInformation.Instance.OperatingSystemVersion); Clipboard.SetContent(dataPackage); }); }
private async Task <IEnumerable <string> > ReadV1PinnedItemsFile() { return(await SafetyExtensions.IgnoreExceptions(async() => { var oldPinnedItemsFile = await ApplicationData.Current.LocalCacheFolder.GetFileAsync("PinnedItems.txt"); var oldPinnedItems = await FileIO.ReadLinesAsync(oldPinnedItemsFile); await oldPinnedItemsFile.DeleteAsync(); return oldPinnedItems; })); }
private async Task <IEnumerable <string> > ReadV2PinnedItemsFile() { return(await SafetyExtensions.IgnoreExceptions(async() => { var oldPinnedItemsFile = await ApplicationData.Current.LocalCacheFolder.GetFileAsync("PinnedItems.json"); var model = JsonConvert.DeserializeObject <SidebarPinnedModel>(await FileIO.ReadTextAsync(oldPinnedItemsFile)); await oldPinnedItemsFile.DeleteAsync(); return model.FavoriteItems; })); }
public static string DecodeEntryName(ZipEntry entry, Encoding zipEncoding) { if (zipEncoding == null || entry.IsUnicodeText) { return(entry.Name); } var decoded = SafetyExtensions.IgnoreExceptions(() => { var rawBytes = Encoding.GetEncoding(Constants.Filesystem.ExtendedAsciiCodePage).GetBytes(entry.Name); return(zipEncoding.GetString(rawBytes)); }); return(decoded ?? entry.Name); }
public static async Task <List <CloudProvider> > DetectCloudDrives() { var tasks = new Task <List <CloudProvider> >[] { SafetyExtensions.IgnoreExceptions(DetectOneDrive, Program.Logger), SafetyExtensions.IgnoreExceptions(DetectSharepoint, Program.Logger), SafetyExtensions.IgnoreExceptions(DetectGenericCloudDrive, Program.Logger), SafetyExtensions.IgnoreExceptions(DetectYandexDisk, Program.Logger), }; await Task.WhenAll(tasks); return(tasks.Where(o => o.Result != null).SelectMany(o => o.Result).OrderBy(o => o.ID.ToString()).ThenBy(o => o.Name).Distinct().ToList()); }
public static ulong?GetFileFRN(string filePath) { //using var si = new ShellItem(filePath); //return (ulong?)si.Properties["System.FileFRN"]; // Leaves open file handles using var hFile = Kernel32.CreateFile(filePath, Kernel32.FileAccess.GENERIC_READ, FileShare.ReadWrite, null, FileMode.Open, FileFlagsAndAttributes.FILE_FLAG_BACKUP_SEMANTICS); if (hFile.IsInvalid) { return(null); } ulong?frn = null; SafetyExtensions.IgnoreExceptions(() => { var fileID = Kernel32.GetFileInformationByHandleEx <Kernel32.FILE_ID_INFO>(hFile, Kernel32.FILE_INFO_BY_HANDLE_CLASS.FileIdInfo); frn = BitConverter.ToUInt64(fileID.FileId.Identifier, 0); }); return(frn); }
/// <summary> /// Invoked when application execution is being suspended. Application state is saved /// without knowing whether the application will be terminated or resumed with the contents /// of memory still intact. /// </summary> /// <param name="sender">The source of the suspend request.</param> /// <param name="e">Details about the suspend request.</param> private async void OnSuspending(object sender, SuspendingEventArgs e) { // Save application state and stop any background activity var deferral = e.SuspendingOperation.GetDeferral(); SaveSessionTabs(); if (OutputPath != null) { await SafetyExtensions.IgnoreExceptions(async() => { var instance = MainPageViewModel.AppInstances.FirstOrDefault(x => x.Control.TabItemContent.IsCurrentInstance); if (instance == null) { return; } var items = (instance.Control.TabItemContent as PaneHolderPage)?.ActivePane?.SlimContentPage?.SelectedItems; if (items == null) { return; } await FileIO.WriteLinesAsync(await StorageFile.GetFileFromPathAsync(OutputPath), items.Select(x => x.ItemPath)); }, Logger); } DrivesManager?.Dispose(); PaneViewModel?.Dispose(); PreviewPaneViewModel?.Dispose(); // Try to maintain clipboard data after app close SafetyExtensions.IgnoreExceptions(() => { var dataPackage = Clipboard.GetContent(); if (dataPackage.Properties.PackageFamilyName == Package.Current.Id.FamilyName) { if (dataPackage.Contains(StandardDataFormats.StorageItems)) { Clipboard.Flush(); } } }, Logger); deferral.Complete(); }
public void UpdateTagsDb() { string fileTagsDbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "filetags.db"); using var dbInstance = new Common.FileTagsDb(fileTagsDbPath, true); foreach (var file in dbInstance.GetAll()) { var pathFromFrn = Win32API.PathFromFileId(file.Frn ?? 0, file.FilePath); if (pathFromFrn != null) { // Frn is valid, update file path var tag = ReadFileTag(pathFromFrn.Replace(@"\\?\", "", StringComparison.Ordinal)); if (tag != null) { dbInstance.UpdateTag(file.Frn ?? 0, null, pathFromFrn.Replace(@"\\?\", "", StringComparison.Ordinal)); dbInstance.SetTag(pathFromFrn.Replace(@"\\?\", "", StringComparison.Ordinal), file.Frn, tag); } else { dbInstance.SetTag(null, file.Frn, null); } } else { var tag = ReadFileTag(file.FilePath); if (tag != null) { if (!SafetyExtensions.IgnoreExceptions(() => { var frn = GetFileFRN(file.FilePath); dbInstance.UpdateTag(file.FilePath, frn, null); dbInstance.SetTag(file.FilePath, (ulong?)frn, tag); }, Program.Logger)) { dbInstance.SetTag(file.FilePath, null, null); } } else { dbInstance.SetTag(file.FilePath, null, null); } } } }
public static ShellLibraryItem GetShellLibraryItem(ShellLibrary2 library, string filePath) { var libraryItem = new ShellLibraryItem { FullPath = filePath, AbsolutePath = library.GetDisplayName(ShellItemDisplayString.DesktopAbsoluteParsing), RelativePath = library.GetDisplayName(ShellItemDisplayString.ParentRelativeParsing), DisplayName = library.GetDisplayName(ShellItemDisplayString.NormalDisplay), IsPinned = library.PinnedToNavigationPane, }; var folders = library.Folders; if (folders.Count > 0) { libraryItem.DefaultSaveFolder = SafetyExtensions.IgnoreExceptions(() => library.DefaultSaveFolder.FileSystemPath); libraryItem.Folders = folders.Select(f => f.FileSystemPath).ToArray(); } return(libraryItem); }
public async Task ParseArgumentsAsync(PipeStream connection, Dictionary <string, object> message, string arguments) { switch (arguments) { case "DetectQuickLook": // Check QuickLook Availability var available = CheckQuickLookAvailability(); await Win32API.SendMessageAsync(connection, new ValueSet() { { "IsAvailable", available } }, message.Get("RequestID", (string)null)); break; case "ToggleQuickLook": var path = (string)message["path"]; var switchPreview = (bool)message["switch"]; SafetyExtensions.IgnoreExceptions(() => ToggleQuickLook(path, switchPreview), Logger); break; } }
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 = SafetyExtensions.IgnoreExceptions(() => 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); } }
public static async Task <CloudTable> CreateTableClientAsync( StorageCredentials credentials, string tableName, bool createTableIfNotExists, ILogger logger) { Ensure.ArgumentNotNullOrWhiteSpace(tableName, nameof(tableName)); Ensure.ArgumentNotNull(credentials, nameof(credentials)); Ensure.ArgumentNotNull(logger, nameof(logger)); var table = default(CloudTable); await SafetyExtensions.ExecuteAsync(logger, async() => { var storageAccount = new CloudStorageAccount(credentials, true); var tableClient = storageAccount.CreateCloudTableClient(); table = tableClient.GetTableReference(tableName); if (createTableIfNotExists) { await table.CreateIfNotExistsAsync() .ConfigureAwait(false); } }); return(table); }
private static async void OnConnectionRequestReceived(Dictionary <string, object> message) { // Get a deferral because we use an awaitable API below to respond to the message // and we don't want this call to get cancelled while we are waiting. if (message == null) { return; } if (message.ContainsKey("Arguments")) { // This replaces launching the fulltrust process with arguments // Instead a single instance of the process is running // Requests from UWP app are sent via AppService connection var arguments = (string)message["Arguments"]; Logger.Info($"Argument: {arguments}"); await SafetyExtensions.IgnoreExceptions(async() => { await Task.Run(() => ParseArgumentsAsync(message, arguments)); }, Logger); } }
public static async Task ToggleQuickLook(IShellPage associatedInstance, bool switchPreview = false) { if (!App.MainViewModel.IsQuickLookEnabled || !associatedInstance.SlimContentPage.IsItemSelected || associatedInstance.SlimContentPage.IsRenamingItem) { return; } await SafetyExtensions.IgnoreExceptions(async() => { Debug.WriteLine("Toggle QuickLook"); var connection = await AppServiceConnectionHelper.Instance; if (connection != null) { await connection.SendMessageAsync(new ValueSet() { { "path", associatedInstance.SlimContentPage.SelectedItem.ItemPath }, { "switch", switchPreview }, { "Arguments", "ToggleQuickLook" } }); } }, App.Logger); }
public static string ToSafeStorageKey(this Guid id) { return(SafetyExtensions.ToLowercaseAlphaNum(id)); }
public async Task ParseArgumentsAsync(PipeStream connection, Dictionary <string, object> message, string arguments) { switch (arguments) { case "LoadContextMenu": var contextMenuResponse = new ValueSet(); var loadThreadWithMessageQueue = new ThreadWithMessageQueue <Dictionary <string, object> >(HandleMenuMessage); var cMenuLoad = await loadThreadWithMessageQueue.PostMessageAsync <ContextMenu>(message); contextMenuResponse.Add("Handle", handleTable.AddValue(loadThreadWithMessageQueue)); contextMenuResponse.Add("ContextMenu", JsonConvert.SerializeObject(cMenuLoad)); await Win32API.SendMessageAsync(connection, contextMenuResponse, message.Get("RequestID", (string)null)); break; case "ExecAndCloseContextMenu": var menuKey = (string)message["Handle"]; var execThreadWithMessageQueue = handleTable.GetValue <ThreadWithMessageQueue <Dictionary <string, object> > >(menuKey); if (execThreadWithMessageQueue != null) { await execThreadWithMessageQueue.PostMessage(message); } // The following line is needed to cleanup resources when menu is closed. // Unfortunately if you uncomment it some menu items will randomly stop working. // Resource cleanup is currently done on app closing, // if we find a solution for the issue above, we should cleanup as soon as a menu is closed. //handleTable.RemoveValue(menuKey); break; case "InvokeVerb": var filePath = (string)message["FilePath"]; var split = filePath.Split('|').Where(x => !string.IsNullOrWhiteSpace(x)); var verb = (string)message["Verb"]; using (var cMenu = ContextMenu.GetContextMenuForFiles(split.ToArray(), Shell32.CMF.CMF_DEFAULTONLY)) { var result = cMenu?.InvokeVerb(verb); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Success", result } }, message.Get("RequestID", (string)null)); } break; case "GetNewContextMenuEntries": var entries = await SafetyExtensions.IgnoreExceptions(() => ShellNewMenuHelper.GetNewContextMenuEntries(), Program.Logger); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Entries", JsonConvert.SerializeObject(entries) } }, message.Get("RequestID", (string)null)); break; case "GetNewContextMenuEntryForType": var fileExtension = (string)message["extension"]; var entry = await SafetyExtensions.IgnoreExceptions(() => ShellNewMenuHelper.GetNewContextMenuEntryForType(fileExtension), Program.Logger); await Win32API.SendMessageAsync(connection, new ValueSet() { { "Entry", JsonConvert.SerializeObject(entry) } }, message.Get("RequestID", (string)null)); break; } }
private static async Task <ShellNewEntry> ParseShellNewRegistryEntry(RegistryKey key, RegistryKey root) { var valueNames = key.GetValueNames(); if (!valueNames.Contains("NullFile", StringComparer.OrdinalIgnoreCase) && !valueNames.Contains("ItemName", StringComparer.OrdinalIgnoreCase) && !valueNames.Contains("FileName", StringComparer.OrdinalIgnoreCase) && !valueNames.Contains("Command", StringComparer.OrdinalIgnoreCase)) { return(null); } var extension = root.Name.Substring(root.Name.LastIndexOf('\\') + 1); var fileName = (string)key.GetValue("FileName"); byte[] data = null; var dataObj = key.GetValue("Data"); if (dataObj != null) { switch (key.GetValueKind("Data")) { case RegistryValueKind.Binary: data = (byte[])dataObj; break; case RegistryValueKind.String: data = UTF8Encoding.UTF8.GetBytes((string)dataObj); break; } } var folder = await SafetyExtensions.IgnoreExceptions(() => ApplicationData.Current.LocalFolder.CreateFolderAsync("extensions", CreationCollisionOption.OpenIfExists).AsTask()); var sampleFile = folder != null ? await SafetyExtensions.IgnoreExceptions(() => folder.CreateFileAsync("file" + extension, CreationCollisionOption.OpenIfExists).AsTask()) : null; var displayType = sampleFile != null ? sampleFile.DisplayType : string.Format("{0} {1}", "file", extension); var thumbnail = sampleFile != null ? await SafetyExtensions.IgnoreExceptions(() => sampleFile.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.ListView, 24, Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale).AsTask()) : null; string iconString = null; if (thumbnail != null) { var readStream = thumbnail.AsStreamForRead(); var bitmapData = new byte[readStream.Length]; await readStream.ReadAsync(bitmapData, 0, bitmapData.Length); iconString = Convert.ToBase64String(bitmapData, 0, bitmapData.Length); } var entry = new ShellNewEntry() { Extension = extension, Template = fileName, Name = displayType, Command = (string)key.GetValue("Command"), IconBase64 = iconString, Data = data }; return(entry); }
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)); } }
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 "ShellFolder": // Enumerate shell folder contents and send response to UWP var folderPath = (string)message["folder"]; var responseEnum = new ValueSet(); var folderContentsList = await Win32API.StartSTATask(() => { var flc = new List <ShellFileItem>(); try { using var shellFolder = new ShellFolder(folderPath); foreach (var folderItem in shellFolder) { try { var shellFileItem = ShellFolderExtensions.GetShellFileItem(folderItem); flc.Add(shellFileItem); } catch (FileNotFoundException) { // Happens if files are being deleted } finally { folderItem.Dispose(); } } } catch { } return(flc); }); responseEnum.Add("Enumerate", JsonConvert.SerializeObject(folderContentsList)); await Win32API.SendMessageAsync(connection, responseEnum, 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.Launcher", "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)); } }