From 1601da81550e403176786414bec57cc1b85b22c4 Mon Sep 17 00:00:00 2001 From: Ray Berezowski <6616212+rberezowski@users.noreply.github.com> Date: Wed, 26 Aug 2026 22:10:55 -0400 Subject: [PATCH] Add run as administrator option --- MainWindow.xaml | 12 ++++++++++-- MainWindow.xaml.cs | 27 +++++++++++++++++++++++++++ Models/LauncherConfig.cs | 2 ++ README.md | 1 + Services/LauncherController.cs | 11 +++++++++++ TaskbarLauncher.csproj | 4 ++-- Views/LauncherPopup.xaml.cs | 25 +++++++++++++++++++++++++ config.example.json | 5 +++++ docs/INSTALL.md | 1 + 9 files changed, 84 insertions(+), 4 deletions(-) diff --git a/MainWindow.xaml b/MainWindow.xaml index ee4d78a..436e446 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -134,6 +134,7 @@ + @@ -212,8 +213,15 @@ - - + + + + DuplicateItem(child, renameRoot: false)).ToList() }; @@ -1781,6 +1785,20 @@ public partial class MainWindow : Window ThemeService.Apply(scheme); } + private void RunAsAdminBox_Changed(object sender, RoutedEventArgs e) + { + if (isLoadingSelection) + { + return; + } + + UpdatePreview(); + if (selectedItem is not null) + { + StatusText.Text = "Click Save to keep the selected item launch options."; + } + } + private void EnsureAutomaticIconPath() { if (TypeBox.SelectedItem is LauncherItemType.Menu) @@ -1860,6 +1878,8 @@ public partial class MainWindow : Window IconPath = string.IsNullOrWhiteSpace(IconPathBox.Text) ? null : IconPathBox.Text.Trim(), IsFavorite = selectedItem.IsFavorite, IsDisabled = selectedItem.IsDisabled, + RunAsAdmin = LauncherController.CanRunAsAdmin(TypeBox.SelectedItem is LauncherItemType itemType ? itemType : LauncherItemType.App) && + RunAsAdminBox.IsChecked == true, DisplayMode = ItemDisplayModeBox.SelectedItem is LauncherDisplayMode mode ? mode : selectedItem.DisplayMode @@ -1926,13 +1946,20 @@ public partial class MainWindow : Window private void UpdateTargetAvailability() { bool isMenu = TypeBox.SelectedItem is LauncherItemType.Menu; + bool canRunAsAdmin = TypeBox.SelectedItem is LauncherItemType itemType && LauncherController.CanRunAsAdmin(itemType); TargetBox.IsEnabled = !isMenu; ArgumentsBox.IsEnabled = !isMenu; + RunAsAdminBox.IsEnabled = canRunAsAdmin; if (isMenu && !isLoadingSelection) { TargetBox.Text = ""; ArgumentsBox.Text = ""; } + + if (!canRunAsAdmin && !isLoadingSelection) + { + RunAsAdminBox.IsChecked = false; + } } protected override void OnClosing(System.ComponentModel.CancelEventArgs e) diff --git a/Models/LauncherConfig.cs b/Models/LauncherConfig.cs index 5aea27c..b09a485 100644 --- a/Models/LauncherConfig.cs +++ b/Models/LauncherConfig.cs @@ -29,6 +29,8 @@ public sealed class LauncherItem public bool IsDisabled { get; set; } + public bool RunAsAdmin { get; set; } + public LauncherDisplayMode DisplayMode { get; set; } = LauncherDisplayMode.CompactList; public List Children { get; set; } = []; diff --git a/README.md b/README.md index f46f679..58b1284 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Download the compiled Windows release from: - Right-click launcher entries to pin or unpin them from the top - Right-click launcher entries or Settings items to temporarily disable them - Right-click app/file entries to open their containing folder +- Optional run-as-administrator mode for app and file entries - Validate missing app, file, and folder targets from Settings - Export and import selected items or menu sections - Sort a selected menu or item level alphabetically diff --git a/Services/LauncherController.cs b/Services/LauncherController.cs index cbcfd69..10e8d74 100644 --- a/Services/LauncherController.cs +++ b/Services/LauncherController.cs @@ -183,6 +183,7 @@ public sealed class LauncherController : IDisposable IconPath = item.IconPath, IsFavorite = false, IsDisabled = false, + RunAsAdmin = item.RunAsAdmin, DisplayMode = item.DisplayMode, Children = [] }; @@ -286,6 +287,11 @@ public sealed class LauncherController : IDisposable WorkingDirectory = Directory.Exists(target) ? target : ConfigService.AppFolder }; + if (item.RunAsAdmin && CanRunAsAdmin(item.Type)) + { + startInfo.Verb = "runas"; + } + Process.Start(startInfo); return true; } @@ -295,4 +301,9 @@ public sealed class LauncherController : IDisposable return false; } } + + public static bool CanRunAsAdmin(LauncherItemType itemType) + { + return itemType is LauncherItemType.App or LauncherItemType.File; + } } diff --git a/TaskbarLauncher.csproj b/TaskbarLauncher.csproj index ff9fbd8..c6c65e4 100644 --- a/TaskbarLauncher.csproj +++ b/TaskbarLauncher.csproj @@ -12,8 +12,8 @@ Ray Berezowski Assets\AppIcon.ico 1.0.1 - 1.0.1.17 - 1.0.1.17 + 1.0.1.18 + 1.0.1.18 1.0.1 diff --git a/Views/LauncherPopup.xaml.cs b/Views/LauncherPopup.xaml.cs index 62472e5..9de70ea 100644 --- a/Views/LauncherPopup.xaml.cs +++ b/Views/LauncherPopup.xaml.cs @@ -216,6 +216,7 @@ public partial class LauncherPopup : Window System.Windows.Controls.ContextMenu contextMenu = new(); contextMenu.Items.Add(CreatePinMenuItem(item)); contextMenu.Items.Add(CreateDisableMenuItem(item)); + contextMenu.Items.Add(CreateRunAsAdminMenuItem(item)); contextMenu.Items.Add(CreateOpenContainingFolderMenuItem(item)); contextMenu.Items.Add(CreateEditMenuItem(item)); return contextMenu; @@ -257,6 +258,25 @@ public partial class LauncherPopup : Window return disableMenuItem; } + private System.Windows.Controls.MenuItem CreateRunAsAdminMenuItem(LauncherItem item) + { + System.Windows.Controls.MenuItem runAsAdminMenuItem = new() + { + Header = item.RunAsAdmin ? "Run as Admin: On" : "Run as Admin: Off", + IsEnabled = LauncherController.CanRunAsAdmin(item.Type) + }; + runAsAdminMenuItem.Click += (_, e) => + { + item.RunAsAdmin = !item.RunAsAdmin; + ConfigService.Save(config); + BuildItems(); + QueueReposition(); + e.Handled = true; + }; + + return runAsAdminMenuItem; + } + private System.Windows.Controls.MenuItem CreateOpenContainingFolderMenuItem(LauncherItem item) { System.Windows.Controls.MenuItem openFolderMenuItem = new() @@ -453,6 +473,11 @@ public partial class LauncherPopup : Window AddToolTipLine(panel, "Pinned to top"); } + if (item.RunAsAdmin) + { + AddToolTipLine(panel, "Runs as administrator"); + } + return new System.Windows.Controls.ToolTip { Content = panel }; } diff --git a/config.example.json b/config.example.json index ad805ea..e50b04e 100644 --- a/config.example.json +++ b/config.example.json @@ -12,6 +12,7 @@ "IconPath": null, "IsFavorite": false, "IsDisabled": false, + "RunAsAdmin": false, "DisplayMode": "CompactList", "Children": [ { @@ -22,6 +23,7 @@ "IconPath": "%USERPROFILE%\\Documents", "IsFavorite": false, "IsDisabled": false, + "RunAsAdmin": false, "DisplayMode": "CompactList", "Children": [] }, @@ -33,6 +35,7 @@ "IconPath": "%USERPROFILE%\\Downloads", "IsFavorite": false, "IsDisabled": false, + "RunAsAdmin": false, "DisplayMode": "CompactList", "Children": [] } @@ -46,6 +49,7 @@ "IconPath": null, "IsFavorite": false, "IsDisabled": false, + "RunAsAdmin": false, "DisplayMode": "CompactList", "Children": [ { @@ -56,6 +60,7 @@ "IconPath": "notepad.exe", "IsFavorite": false, "IsDisabled": false, + "RunAsAdmin": false, "DisplayMode": "CompactList", "Children": [] } diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 278fb84..7ac396e 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -47,6 +47,7 @@ From Settings you can: - Right-click an item and choose **Pin to Top** to show it first in its menu - Right-click an item and choose **Disable Item** or **Enable Item** to hide or restore it - Right-click an app or file item and choose **Open Containing Folder** +- Enable **Run as administrator** for app and file items that need elevation - Use **Config... > Validate Targets** to check for missing app, file, and folder targets - Use **Config... > Export Selected Item** or **Import Item** to share one item or menu section - Right-click an item and choose **Sort This Menu** or **Sort This Level**