private static object HandleMenuMessage(ValueSet message, Win32API.DisposableDictionary table) { switch ((string)message["Arguments"]) { case "LoadContextMenu": var contextMenuResponse = new ValueSet(); var filePath = (string)message["FilePath"]; var extendedMenu = (bool)message["ExtendedMenu"]; var showOpenMenu = (bool)message["ShowOpenMenu"]; var split = filePath.Split('|').Where(x => !string.IsNullOrWhiteSpace(x)); var cMenuLoad = Win32API.ContextMenu.GetContextMenuForFiles(split.ToArray(), extendedMenu ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL, FilterMenuItems(showOpenMenu)); table.SetValue("MENU", cMenuLoad); return(cMenuLoad); case "ExecAndCloseContextMenu": var cMenuExec = table.GetValue <Win32API.ContextMenu>("MENU"); cMenuExec?.InvokeItem(message.Get("ItemID", -1)); // 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. //table.RemoveValue("MENU"); return(null); default: return(null); } }
private static async Task parseArguments(AppServiceRequestReceivedEventArgs args, AppServiceDeferral messageDeferral, string arguments, ApplicationDataContainer localSettings) { switch (arguments) { case "Terminate": // Exit fulltrust process (UWP is closed or suspended) appServiceExit.Set(); messageDeferral.Complete(); break; case "RecycleBin": var binAction = (string)args.Request.Message["action"]; await parseRecycleBinAction(args, binAction); break; case "StartupTasks": // Check QuickLook Availability QuickLook.CheckQuickLookAvailability(localSettings); break; case "ToggleQuickLook": var path = (string)args.Request.Message["path"]; QuickLook.ToggleQuickLook(path); break; case "ShellCommand": // Kill the process. This is a BRUTAL WAY to kill a process. #if DEBUG // In debug mode this kills this process too?? #else var pid = (int)args.Request.Message["pid"]; Process.GetProcessById(pid).Kill(); #endif Process process = new Process(); process.StartInfo.UseShellExecute = true; process.StartInfo.FileName = "explorer.exe"; process.StartInfo.CreateNoWindow = false; process.StartInfo.Arguments = (string)args.Request.Message["ShellCommand"]; process.Start(); break; case "LoadContextMenu": var contextMenuResponse = new ValueSet(); var loadThreadWithMessageQueue = new Win32API.ThreadWithMessageQueue <ValueSet>(HandleMenuMessage); var cMenuLoad = await loadThreadWithMessageQueue.PostMessage <Win32API.ContextMenu>(args.Request.Message); contextMenuResponse.Add("Handle", handleTable.AddValue(loadThreadWithMessageQueue)); contextMenuResponse.Add("ContextMenu", JsonConvert.SerializeObject(cMenuLoad)); await args.Request.SendResponseAsync(contextMenuResponse); break; case "ExecAndCloseContextMenu": var menuKey = (string)args.Request.Message["Handle"]; var execThreadWithMessageQueue = handleTable.GetValue <Win32API.ThreadWithMessageQueue <ValueSet> >(menuKey); if (execThreadWithMessageQueue != null) { await execThreadWithMessageQueue.PostMessage(args.Request.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)args.Request.Message["FilePath"]; var split = filePath.Split('|').Where(x => !string.IsNullOrWhiteSpace(x)); using (var cMenu = Win32API.ContextMenu.GetContextMenuForFiles(split.ToArray(), Shell32.CMF.CMF_DEFAULTONLY)) { cMenu?.InvokeVerb((string)args.Request.Message["Verb"]); } break; case "Bitlocker": var bitlockerAction = (string)args.Request.Message["action"]; if (bitlockerAction == "Unlock") { var drive = (string)args.Request.Message["drive"]; var password = (string)args.Request.Message["password"]; Win32API.UnlockBitlockerDrive(drive, password); await args.Request.SendResponseAsync(new ValueSet() { { "Bitlocker", "Unlock" } }); } break; case "FileOperation": await parseFileOperation(args); break; default: if (args.Request.Message.ContainsKey("Application")) { var application = (string)args.Request.Message["Application"]; HandleApplicationLaunch(application, args); } else if (args.Request.Message.ContainsKey("ApplicationList")) { var applicationList = JsonConvert.DeserializeObject <IEnumerable <string> >((string)args.Request.Message["ApplicationList"]); HandleApplicationsLaunch(applicationList, args); } break; } }
private static async Task ParseArgumentsAsync(AppServiceRequestReceivedEventArgs args, AppServiceDeferral messageDeferral, string arguments, ApplicationDataContainer localSettings) { switch (arguments) { case "Terminate": // Exit fulltrust process (UWP is closed or suspended) appServiceExit.Set(); messageDeferral.Complete(); break; case "RecycleBin": var binAction = (string)args.Request.Message["action"]; await ParseRecycleBinActionAsync(args, binAction); break; case "StartupTasks": // Check QuickLook Availability QuickLook.CheckQuickLookAvailability(localSettings); break; case "ToggleQuickLook": var path = (string)args.Request.Message["path"]; QuickLook.ToggleQuickLook(path); break; case "ShellCommand": // Kill the process. This is a BRUTAL WAY to kill a process. #if DEBUG // In debug mode this kills this process too?? #else var pid = (int)args.Request.Message["pid"]; Process.GetProcessById(pid).Kill(); #endif Process process = new Process(); process.StartInfo.UseShellExecute = true; process.StartInfo.FileName = "explorer.exe"; process.StartInfo.CreateNoWindow = false; process.StartInfo.Arguments = (string)args.Request.Message["ShellCommand"]; process.Start(); break; case "LoadContextMenu": var contextMenuResponse = new ValueSet(); var loadThreadWithMessageQueue = new Win32API.ThreadWithMessageQueue <ValueSet>(HandleMenuMessage); var cMenuLoad = await loadThreadWithMessageQueue.PostMessageAsync <Win32API.ContextMenu>(args.Request.Message); contextMenuResponse.Add("Handle", handleTable.AddValue(loadThreadWithMessageQueue)); contextMenuResponse.Add("ContextMenu", JsonConvert.SerializeObject(cMenuLoad)); await args.Request.SendResponseAsync(contextMenuResponse); break; case "ExecAndCloseContextMenu": var menuKey = (string)args.Request.Message["Handle"]; var execThreadWithMessageQueue = handleTable.GetValue <Win32API.ThreadWithMessageQueue <ValueSet> >(menuKey); if (execThreadWithMessageQueue != null) { await execThreadWithMessageQueue.PostMessage(args.Request.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)args.Request.Message["FilePath"]; var split = filePath.Split('|').Where(x => !string.IsNullOrWhiteSpace(x)); using (var cMenu = Win32API.ContextMenu.GetContextMenuForFiles(split.ToArray(), Shell32.CMF.CMF_DEFAULTONLY)) { cMenu?.InvokeVerb((string)args.Request.Message["Verb"]); } break; case "Bitlocker": var bitlockerAction = (string)args.Request.Message["action"]; if (bitlockerAction == "Unlock") { var drive = (string)args.Request.Message["drive"]; var password = (string)args.Request.Message["password"]; Win32API.UnlockBitlockerDrive(drive, password); await args.Request.SendResponseAsync(new ValueSet() { { "Bitlocker", "Unlock" } }); } break; case "SetVolumeLabel": var driveName = (string)args.Request.Message["drivename"]; var newLabel = (string)args.Request.Message["newlabel"]; Win32API.SetVolumeLabel(driveName, newLabel); break; case "FileOperation": await ParseFileOperationAsync(args); break; case "GetIconOverlay": var fileIconPath = (string)args.Request.Message["filePath"]; var thumbnailSize = (int)args.Request.Message["thumbnailSize"]; var iconOverlay = Win32API.GetFileIconAndOverlay(fileIconPath, thumbnailSize); await args.Request.SendResponseAsync(new ValueSet() { { "Icon", iconOverlay.icon }, { "Overlay", iconOverlay.overlay }, { "HasCustomIcon", iconOverlay.isCustom } }); break; case "GetOneDriveAccounts": using (var oneDriveAccountsKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\OneDrive\Accounts", false)) { var oneDriveAccounts = new ValueSet(); foreach (var account in oneDriveAccountsKey.GetSubKeyNames()) { var accountKeyName = @$ "{oneDriveAccountsKey.Name}\{account}"; var displayName = (string)Registry.GetValue(accountKeyName, "DisplayName", null); var userFolder = (string)Registry.GetValue(accountKeyName, "UserFolder", null); var accountName = string.IsNullOrWhiteSpace(displayName) ? "OneDrive" : $"OneDrive - {displayName}"; if (!string.IsNullOrWhiteSpace(userFolder) && !oneDriveAccounts.ContainsKey(accountName)) { oneDriveAccounts.Add(accountName, userFolder); } } await args.Request.SendResponseAsync(oneDriveAccounts); } break;