RunExeItem.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using Microsoft.CmdPal.Core.Common.Services; 6 using Microsoft.CmdPal.Ext.Shell.Helpers; 7 using Microsoft.CommandPalette.Extensions; 8 using Microsoft.CommandPalette.Extensions.Toolkit; 9 using Windows.Storage.Streams; 10 using Windows.System; 11 12 namespace Microsoft.CmdPal.Ext.Shell.Pages; 13 14 internal sealed partial class RunExeItem : ListItem 15 { 16 private readonly Lazy<IconInfo> _icon; 17 private readonly Action<string>? _addToHistory; 18 private readonly ITelemetryService? _telemetryService; 19 20 public override IIconInfo? Icon { get => _icon.Value; set => base.Icon = value; } 21 22 internal string FullExePath { get; private set; } 23 24 internal string Exe { get; private set; } 25 26 private string _args = string.Empty; 27 28 private string FullString => string.IsNullOrEmpty(_args) ? Exe : $"{Exe} {_args}"; 29 30 public RunExeItem( 31 string exe, 32 string args, 33 string fullExePath, 34 Action<string>? addToHistory, 35 ITelemetryService? telemetryService = null) 36 { 37 FullExePath = fullExePath; 38 Exe = exe; 39 var command = new AnonymousCommand(Run) 40 { 41 Name = ResourceLoaderInstance.GetString("generic_run_command"), 42 Result = CommandResult.Dismiss(), 43 }; 44 Command = command; 45 Subtitle = FullExePath; 46 47 _icon = new Lazy<IconInfo>(() => 48 { 49 var t = FetchIcon(); 50 t.Wait(); 51 return t.Result; 52 }); 53 54 _addToHistory = addToHistory; 55 _telemetryService = telemetryService; 56 57 UpdateArgs(args); 58 59 MoreCommands = [ 60 new CommandContextItem( 61 new AnonymousCommand(RunAsAdmin) 62 { 63 Name = ResourceLoaderInstance.GetString("cmd_run_as_administrator"), 64 Icon = Icons.AdminIcon, 65 }) { RequestedShortcut = KeyChordHelpers.FromModifiers(ctrl: true, shift: true, vkey: VirtualKey.Enter) }, 66 new CommandContextItem( 67 new AnonymousCommand(RunAsOther) 68 { 69 Name = ResourceLoaderInstance.GetString("cmd_run_as_user"), 70 Icon = Icons.UserIcon, 71 }) { RequestedShortcut = KeyChordHelpers.FromModifiers(ctrl: true, shift: true, vkey: VirtualKey.U) }, 72 ]; 73 } 74 75 internal void UpdateArgs(string args) 76 { 77 _args = args; 78 Title = string.IsNullOrEmpty(_args) ? Exe : Exe + " " + _args; // todo! you're smarter than this 79 } 80 81 public async Task<IconInfo> FetchIcon() 82 { 83 IconInfo? icon = null; 84 85 try 86 { 87 var stream = await ThumbnailHelper.GetThumbnail(FullExePath); 88 if (stream is not null) 89 { 90 var data = new IconData(RandomAccessStreamReference.CreateFromStream(stream)); 91 icon = new IconInfo(data, data); 92 ((AnonymousCommand?)Command)!.Icon = icon; 93 } 94 } 95 catch 96 { 97 } 98 99 icon = icon ?? new IconInfo(FullExePath); 100 return icon; 101 } 102 103 public void Run() 104 { 105 _addToHistory?.Invoke(FullString); 106 107 var success = ShellHelpers.OpenInShell(FullExePath, _args); 108 109 _telemetryService?.LogRunCommand(FullString, false, success); 110 } 111 112 public void RunAsAdmin() 113 { 114 _addToHistory?.Invoke(FullString); 115 116 var success = ShellHelpers.OpenInShell(FullExePath, _args, runAs: ShellHelpers.ShellRunAsType.Administrator); 117 118 _telemetryService?.LogRunCommand(FullString, true, success); 119 } 120 121 public void RunAsOther() 122 { 123 _addToHistory?.Invoke(FullString); 124 125 var success = ShellHelpers.OpenInShell(FullExePath, _args, runAs: ShellHelpers.ShellRunAsType.OtherUser); 126 127 _telemetryService?.LogRunCommand(FullString, false, success); 128 } 129 }