mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 21:41:51 +02:00
[PT Run] Run as user feature (#17283)
* run as different user * fix tests * Update src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs * fix typo
This commit is contained in:
@@ -28,7 +28,7 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
File,
|
File,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extensions for adding run as admin context menu item for applications
|
// Extensions for adding run as admin and run as other user context menu item for applications
|
||||||
private readonly string[] appExtensions = { ".exe", ".bat", ".appref-ms", ".lnk" };
|
private readonly string[] appExtensions = { ".exe", ".bat", ".appref-ms", ".lnk" };
|
||||||
|
|
||||||
public ContextMenuLoader(PluginInitContext context)
|
public ContextMenuLoader(PluginInitContext context)
|
||||||
@@ -53,6 +53,7 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
if (CanFileBeRunAsAdmin(record.Path))
|
if (CanFileBeRunAsAdmin(record.Path))
|
||||||
{
|
{
|
||||||
contextMenus.Add(CreateRunAsAdminContextMenu(record));
|
contextMenus.Add(CreateRunAsAdminContextMenu(record));
|
||||||
|
contextMenus.Add(CreateRunAsUserContextMenu(record));
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenus.Add(new ContextMenuResult
|
contextMenus.Add(new ContextMenuResult
|
||||||
@@ -145,6 +146,34 @@ namespace Microsoft.Plugin.Indexer
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to add the context menu item to run as admin
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive, and instead log the exception message")]
|
||||||
|
private static ContextMenuResult CreateRunAsUserContextMenu(SearchResult record)
|
||||||
|
{
|
||||||
|
return new ContextMenuResult
|
||||||
|
{
|
||||||
|
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||||
|
Title = Properties.Resources.Microsoft_plugin_indexer_run_as_user,
|
||||||
|
Glyph = "\xE7EE",
|
||||||
|
FontFamily = "Segoe MDL2 Assets",
|
||||||
|
AcceleratorKey = Key.U,
|
||||||
|
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Task.Run(() => Helper.RunAsUser(record.Path));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Exception($"Failed to run {record.Path} as different user, {e.Message}", e, MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Function to test if the file can be run as admin
|
// Function to test if the file can be run as admin
|
||||||
private bool CanFileBeRunAsAdmin(string path)
|
private bool CanFileBeRunAsAdmin(string path)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
public class Resources {
|
public class Resources {
|
||||||
@@ -61,7 +61,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Disable drive detection warning.
|
/// Looks up a localized string similar to Disable non-indexed files warning.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string disable_drive_detection_warning {
|
public static string disable_drive_detection_warning {
|
||||||
get {
|
get {
|
||||||
@@ -186,6 +186,15 @@ namespace Microsoft.Plugin.Indexer.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Run as different user (Ctrl+Shift+U).
|
||||||
|
/// </summary>
|
||||||
|
public static string Microsoft_plugin_indexer_run_as_user {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Microsoft_plugin_indexer_run_as_user", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Search.
|
/// Looks up a localized string similar to Search.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -162,4 +162,7 @@
|
|||||||
<data name="disable_drive_detection_warning" xml:space="preserve">
|
<data name="disable_drive_detection_warning" xml:space="preserve">
|
||||||
<value>Disable non-indexed files warning</value>
|
<value>Disable non-indexed files warning</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
<data name="Microsoft_plugin_indexer_run_as_user" xml:space="preserve">
|
||||||
|
<value>Run as different user (Ctrl+Shift+U)</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -466,10 +466,11 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
|||||||
List<ContextMenuResult> contextMenuResults = _pinnedWebpage.ContextMenus(string.Empty, mock.Object);
|
List<ContextMenuResult> contextMenuResults = _pinnedWebpage.ContextMenus(string.Empty, mock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, contextMenuResults.Count);
|
Assert.AreEqual(4, contextMenuResults.Count);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[1].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_user, contextMenuResults[1].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[2].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[2].Title);
|
||||||
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[3].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@@ -497,10 +498,11 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
|||||||
List<ContextMenuResult> contextMenuResults = _chrome.ContextMenus(string.Empty, mock.Object);
|
List<ContextMenuResult> contextMenuResults = _chrome.ContextMenus(string.Empty, mock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, contextMenuResults.Count);
|
Assert.AreEqual(4, contextMenuResults.Count);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[1].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_user, contextMenuResults[1].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[2].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[2].Title);
|
||||||
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[3].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@@ -513,10 +515,11 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
|||||||
List<ContextMenuResult> contextMenuResults = _cmdRunCommand.ContextMenus(string.Empty, mock.Object);
|
List<ContextMenuResult> contextMenuResults = _cmdRunCommand.ContextMenus(string.Empty, mock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, contextMenuResults.Count);
|
Assert.AreEqual(4, contextMenuResults.Count);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[1].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_user, contextMenuResults[1].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[2].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[2].Title);
|
||||||
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[3].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@@ -529,10 +532,11 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
|||||||
List<ContextMenuResult> contextMenuResults = _dummyAppRefApp.ContextMenus(string.Empty, mock.Object);
|
List<ContextMenuResult> contextMenuResults = _dummyAppRefApp.ContextMenus(string.Empty, mock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, contextMenuResults.Count);
|
Assert.AreEqual(4, contextMenuResults.Count);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[1].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_user, contextMenuResults[1].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[2].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[2].Title);
|
||||||
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[3].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@@ -545,10 +549,11 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
|
|||||||
List<ContextMenuResult> contextMenuResults = _dummyShortcutApp.ContextMenus(string.Empty, mock.Object);
|
List<ContextMenuResult> contextMenuResults = _dummyShortcutApp.ContextMenus(string.Empty, mock.Object);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(3, contextMenuResults.Count);
|
Assert.AreEqual(4, contextMenuResults.Count);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_administrator, contextMenuResults[0].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[1].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_run_as_user, contextMenuResults[1].Title);
|
||||||
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[2].Title);
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_containing_folder, contextMenuResults[2].Title);
|
||||||
|
Assert.AreEqual(Properties.Resources.wox_plugin_program_open_in_console, contextMenuResults[3].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// We don't add context menu to 'run as different user', because UWP applications normally installed per user and not for all users.
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenus.Add(
|
contextMenus.Add(
|
||||||
|
|||||||
@@ -266,7 +266,24 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||||
Action = _ =>
|
Action = _ =>
|
||||||
{
|
{
|
||||||
var info = GetProcessStartInfo(queryArguments, true);
|
var info = GetProcessStartInfo(queryArguments, RunAsType.Administrator);
|
||||||
|
Task.Run(() => Main.StartProcess(Process.Start, info));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
contextMenus.Add(new ContextMenuResult
|
||||||
|
{
|
||||||
|
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||||
|
Title = Properties.Resources.wox_plugin_program_run_as_user,
|
||||||
|
Glyph = "\xE7EE",
|
||||||
|
FontFamily = "Segoe MDL2 Assets",
|
||||||
|
AcceleratorKey = Key.U,
|
||||||
|
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
var info = GetProcessStartInfo(queryArguments, RunAsType.OtherUser);
|
||||||
Task.Run(() => Main.StartProcess(Process.Start, info));
|
Task.Run(() => Main.StartProcess(Process.Start, info));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -317,7 +334,7 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
return contextMenus;
|
return contextMenus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProcessStartInfo GetProcessStartInfo(string programArguments, bool runAsAdmin = false)
|
private ProcessStartInfo GetProcessStartInfo(string programArguments, RunAsType runAs = RunAsType.None)
|
||||||
{
|
{
|
||||||
return new ProcessStartInfo
|
return new ProcessStartInfo
|
||||||
{
|
{
|
||||||
@@ -325,10 +342,17 @@ namespace Microsoft.Plugin.Program.Programs
|
|||||||
WorkingDirectory = ParentDirectory,
|
WorkingDirectory = ParentDirectory,
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
Arguments = programArguments,
|
Arguments = programArguments,
|
||||||
Verb = runAsAdmin ? "runas" : string.Empty,
|
Verb = runAs == RunAsType.Administrator ? "runAs" : runAs == RunAsType.OtherUser ? "runAsUser" : string.Empty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum RunAsType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Administrator,
|
||||||
|
OtherUser,
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return ExecutableName;
|
return ExecutableName;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Microsoft.Plugin.Program.Properties {
|
|||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
public class Resources {
|
public class Resources {
|
||||||
@@ -203,5 +203,14 @@ namespace Microsoft.Plugin.Program.Properties {
|
|||||||
return ResourceManager.GetString("wox_plugin_program_run_as_administrator", resourceCulture);
|
return ResourceManager.GetString("wox_plugin_program_run_as_administrator", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Run as different user (Ctrl+Shift+U).
|
||||||
|
/// </summary>
|
||||||
|
public static string wox_plugin_program_run_as_user {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("wox_plugin_program_run_as_user", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,4 +165,7 @@
|
|||||||
<data name="powertoys_run_plugin_program_uwp_failed" xml:space="preserve">
|
<data name="powertoys_run_plugin_program_uwp_failed" xml:space="preserve">
|
||||||
<value>Can't start UWP</value>
|
<value>Can't start UWP</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="wox_plugin_program_run_as_user" xml:space="preserve">
|
||||||
|
<value>Run as different user (Ctrl+Shift+U)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -153,19 +153,29 @@ namespace Microsoft.Plugin.Shell
|
|||||||
return history.ToList();
|
return history.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProcessStartInfo PrepareProcessStartInfo(string command, bool runAsAdministrator = false)
|
private ProcessStartInfo PrepareProcessStartInfo(string command, RunAsType runAs = RunAsType.None)
|
||||||
{
|
{
|
||||||
string trimmedCommand = command.Trim();
|
string trimmedCommand = command.Trim();
|
||||||
command = Environment.ExpandEnvironmentVariables(trimmedCommand);
|
command = Environment.ExpandEnvironmentVariables(trimmedCommand);
|
||||||
var workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
var workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||||
var runAsAdministratorArg = !runAsAdministrator && !_settings.RunAsAdministrator ? string.Empty : "runas";
|
|
||||||
|
// Set runAsArg
|
||||||
|
string runAsVerbArg = string.Empty;
|
||||||
|
if (runAs == RunAsType.OtherUser)
|
||||||
|
{
|
||||||
|
runAsVerbArg = "runAsUser";
|
||||||
|
}
|
||||||
|
else if (runAs == RunAsType.Administrator || _settings.RunAsAdministrator)
|
||||||
|
{
|
||||||
|
runAsVerbArg = "runAs";
|
||||||
|
}
|
||||||
|
|
||||||
ProcessStartInfo info;
|
ProcessStartInfo info;
|
||||||
if (_settings.Shell == ExecutionShell.Cmd)
|
if (_settings.Shell == ExecutionShell.Cmd)
|
||||||
{
|
{
|
||||||
var arguments = _settings.LeaveShellOpen ? $"/k \"{command}\"" : $"/c \"{command}\" & pause";
|
var arguments = _settings.LeaveShellOpen ? $"/k \"{command}\"" : $"/c \"{command}\" & pause";
|
||||||
|
|
||||||
info = ShellCommand.SetProcessStartInfo("cmd.exe", workingDirectory, arguments, runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo("cmd.exe", workingDirectory, arguments, runAsVerbArg);
|
||||||
}
|
}
|
||||||
else if (_settings.Shell == ExecutionShell.Powershell)
|
else if (_settings.Shell == ExecutionShell.Powershell)
|
||||||
{
|
{
|
||||||
@@ -179,14 +189,14 @@ namespace Microsoft.Plugin.Shell
|
|||||||
arguments = $"\"{command} ; Read-Host -Prompt \\\"Press Enter to continue\\\"\"";
|
arguments = $"\"{command} ; Read-Host -Prompt \\\"Press Enter to continue\\\"\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
info = ShellCommand.SetProcessStartInfo("powershell.exe", workingDirectory, arguments, runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo("powershell.exe", workingDirectory, arguments, runAsVerbArg);
|
||||||
}
|
}
|
||||||
else if (_settings.Shell == ExecutionShell.RunCommand)
|
else if (_settings.Shell == ExecutionShell.RunCommand)
|
||||||
{
|
{
|
||||||
// Open explorer if the path is a file or directory
|
// Open explorer if the path is a file or directory
|
||||||
if (Directory.Exists(command) || File.Exists(command))
|
if (Directory.Exists(command) || File.Exists(command))
|
||||||
{
|
{
|
||||||
info = ShellCommand.SetProcessStartInfo("explorer.exe", arguments: command, verb: runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo("explorer.exe", arguments: command, verb: runAsVerbArg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -197,16 +207,16 @@ namespace Microsoft.Plugin.Shell
|
|||||||
if (ExistInPath(filename))
|
if (ExistInPath(filename))
|
||||||
{
|
{
|
||||||
var arguments = parts[1];
|
var arguments = parts[1];
|
||||||
info = ShellCommand.SetProcessStartInfo(filename, workingDirectory, arguments, runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo(filename, workingDirectory, arguments, runAsVerbArg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info = ShellCommand.SetProcessStartInfo(command, verb: runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo(command, verb: runAsVerbArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info = ShellCommand.SetProcessStartInfo(command, verb: runAsAdministratorArg);
|
info = ShellCommand.SetProcessStartInfo(command, verb: runAsVerbArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,6 +232,13 @@ namespace Microsoft.Plugin.Shell
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum RunAsType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Administrator,
|
||||||
|
OtherUser,
|
||||||
|
}
|
||||||
|
|
||||||
private void Execute(Func<ProcessStartInfo, Process> startProcess, ProcessStartInfo info)
|
private void Execute(Func<ProcessStartInfo, Process> startProcess, ProcessStartInfo info)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -326,7 +343,21 @@ namespace Microsoft.Plugin.Shell
|
|||||||
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, true));
|
Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, RunAsType.Administrator));
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
new ContextMenuResult
|
||||||
|
{
|
||||||
|
PluginName = Assembly.GetExecutingAssembly().GetName().Name,
|
||||||
|
Title = Properties.Resources.wox_plugin_cmd_run_as_user,
|
||||||
|
Glyph = "\xE7EE",
|
||||||
|
FontFamily = "Segoe MDL2 Assets",
|
||||||
|
AcceleratorKey = Key.U,
|
||||||
|
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
|
||||||
|
Action = _ =>
|
||||||
|
{
|
||||||
|
Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, RunAsType.OtherUser));
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Microsoft.Plugin.Shell.Properties {
|
|||||||
// class via a tool like ResGen or Visual Studio.
|
// class via a tool like ResGen or Visual Studio.
|
||||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
// with the /str option, or rebuild your VS project.
|
// with the /str option, or rebuild your VS project.
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
public class Resources {
|
public class Resources {
|
||||||
@@ -122,5 +122,14 @@ namespace Microsoft.Plugin.Shell.Properties {
|
|||||||
return ResourceManager.GetString("wox_plugin_cmd_run_as_administrator", resourceCulture);
|
return ResourceManager.GetString("wox_plugin_cmd_run_as_administrator", resourceCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Run as different user (Ctrl+Shift+U).
|
||||||
|
/// </summary>
|
||||||
|
public static string wox_plugin_cmd_run_as_user {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("wox_plugin_cmd_run_as_user", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,4 +138,7 @@
|
|||||||
<data name="wox_plugin_cmd_command_not_found" xml:space="preserve">
|
<data name="wox_plugin_cmd_command_not_found" xml:space="preserve">
|
||||||
<value>Command not found</value>
|
<value>Command not found</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="wox_plugin_cmd_run_as_user" xml:space="preserve">
|
||||||
|
<value>Run as different user (Ctrl+Shift+U)</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -186,7 +186,7 @@ namespace Microsoft.Plugin.WindowWalker.Components
|
|||||||
if (IsFullAccessDenied)
|
if (IsFullAccessDenied)
|
||||||
{
|
{
|
||||||
string killTree = killProcessTree ? " /t" : string.Empty;
|
string killTree = killProcessTree ? " /t" : string.Empty;
|
||||||
Helper.OpenInShell("taskkill.exe", $"/pid {(int)ProcessID} /f{killTree}", null, true, true);
|
Helper.OpenInShell("taskkill.exe", $"/pid {(int)ProcessID} /f{killTree}", null, Helper.ShellRunAsType.Administrator, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Helper
|
|||||||
Win32.Registry.SetValue(@"HKEY_Current_User\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", "LastKey", fullKey);
|
Win32.Registry.SetValue(@"HKEY_Current_User\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit", "LastKey", fullKey);
|
||||||
|
|
||||||
// -m => allow multi-instance (hidden start option)
|
// -m => allow multi-instance (hidden start option)
|
||||||
Wox.Infrastructure.Helper.OpenInShell("regedit.exe", "-m", null, true);
|
Wox.Infrastructure.Helper.OpenInShell("regedit.exe", "-m", null, Wox.Infrastructure.Helper.ShellRunAsType.Administrator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.Components
|
|||||||
IcoPath = $"Images\\firmwareSettings.{iconTheme}.png",
|
IcoPath = $"Images\\firmwareSettings.{iconTheme}.png",
|
||||||
Action = c =>
|
Action = c =>
|
||||||
{
|
{
|
||||||
return ResultHelper.ExecuteCommand(confirmCommands, Resources.Microsoft_plugin_sys_uefi_confirmation, () => Helper.OpenInShell("shutdown", "/r /fw /t 0", null, true));
|
return ResultHelper.ExecuteCommand(confirmCommands, Resources.Microsoft_plugin_sys_uefi_confirmation, () => Helper.OpenInShell("shutdown", "/r /fw /t 0", null, Helper.ShellRunAsType.Administrator));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
string path = "shell:AppsFolder\\" + id;
|
string path = "shell:AppsFolder\\" + id;
|
||||||
Helper.OpenInShell(path, TerminalHelper.GetArguments(profile, _openNewTab), runAsAdmin: true);
|
Helper.OpenInShell(path, TerminalHelper.GetArguments(profile, _openNewTab), runAs: Helper.ShellRunAsType.Administrator);
|
||||||
}
|
}
|
||||||
#pragma warning disable CA1031 // Do not catch general exception types
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Wox.Infrastructure
|
|||||||
{
|
{
|
||||||
FileName = path,
|
FileName = path,
|
||||||
WorkingDirectory = Path.GetDirectoryName(path),
|
WorkingDirectory = Path.GetDirectoryName(path),
|
||||||
Verb = "runas",
|
Verb = "runAs",
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,6 +115,28 @@ namespace Wox.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function to run as other user for context menu items
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
|
||||||
|
public static void RunAsUser(string path)
|
||||||
|
{
|
||||||
|
var info = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = path,
|
||||||
|
WorkingDirectory = Path.GetDirectoryName(path),
|
||||||
|
Verb = "runAsUser",
|
||||||
|
UseShellExecute = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(info);
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Log.Exception($"Unable to Run {path} as different user : {ex.Message}", ex, MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Process OpenInConsole(string path)
|
public static Process OpenInConsole(string path)
|
||||||
{
|
{
|
||||||
var processStartInfo = new ProcessStartInfo
|
var processStartInfo = new ProcessStartInfo
|
||||||
@@ -126,7 +148,7 @@ namespace Wox.Infrastructure
|
|||||||
return Process.Start(processStartInfo);
|
return Process.Start(processStartInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool OpenInShell(string path, string arguments = null, string workingDir = null, bool runAsAdmin = false, bool runWithHiddenWindow = false)
|
public static bool OpenInShell(string path, string arguments = null, string workingDir = null, ShellRunAsType runAs = ShellRunAsType.None, bool runWithHiddenWindow = false)
|
||||||
{
|
{
|
||||||
using (var process = new Process())
|
using (var process = new Process())
|
||||||
{
|
{
|
||||||
@@ -134,13 +156,16 @@ namespace Wox.Infrastructure
|
|||||||
process.StartInfo.WorkingDirectory = string.IsNullOrWhiteSpace(workingDir) ? string.Empty : workingDir;
|
process.StartInfo.WorkingDirectory = string.IsNullOrWhiteSpace(workingDir) ? string.Empty : workingDir;
|
||||||
process.StartInfo.Arguments = string.IsNullOrWhiteSpace(arguments) ? string.Empty : arguments;
|
process.StartInfo.Arguments = string.IsNullOrWhiteSpace(arguments) ? string.Empty : arguments;
|
||||||
process.StartInfo.WindowStyle = runWithHiddenWindow ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal;
|
process.StartInfo.WindowStyle = runWithHiddenWindow ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal;
|
||||||
|
process.StartInfo.UseShellExecute = true;
|
||||||
|
|
||||||
if (runAsAdmin)
|
if (runAs == ShellRunAsType.Administrator)
|
||||||
{
|
{
|
||||||
process.StartInfo.Verb = "RunAs";
|
process.StartInfo.Verb = "RunAs";
|
||||||
}
|
}
|
||||||
|
else if (runAs == ShellRunAsType.OtherUser)
|
||||||
process.StartInfo.UseShellExecute = true;
|
{
|
||||||
|
process.StartInfo.Verb = "RunAsUser";
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -154,5 +179,12 @@ namespace Wox.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ShellRunAsType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Administrator,
|
||||||
|
OtherUser,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,11 +291,12 @@ namespace Wox.Test.Plugins
|
|||||||
List<ContextMenuResult> contextMenuItems = contextMenuLoader.LoadContextMenus(result);
|
List<ContextMenuResult> contextMenuItems = contextMenuLoader.LoadContextMenus(result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.AreEqual(4, contextMenuItems.Count);
|
Assert.AreEqual(5, contextMenuItems.Count);
|
||||||
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_open_containing_folder, contextMenuItems[0].Title);
|
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_open_containing_folder, contextMenuItems[0].Title);
|
||||||
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_run_as_administrator, contextMenuItems[1].Title);
|
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_run_as_administrator, contextMenuItems[1].Title);
|
||||||
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_copy_path, contextMenuItems[2].Title);
|
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_run_as_user, contextMenuItems[2].Title);
|
||||||
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_open_in_console, contextMenuItems[3].Title);
|
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_copy_path, contextMenuItems[3].Title);
|
||||||
|
Assert.AreEqual(Microsoft.Plugin.Indexer.Properties.Resources.Microsoft_plugin_indexer_open_in_console, contextMenuItems[4].Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataTestMethod]
|
[DataTestMethod]
|
||||||
|
|||||||
Reference in New Issue
Block a user