Add ability to run as a different user for win32 programs

This commit is contained in:
Jeremy Wu
2019-12-10 22:01:12 +11:00
parent 9855e2edee
commit 695be89656
7 changed files with 77 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -31,6 +31,7 @@
<system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String> <system:String x:Key="wox_plugin_program_update_file_suffixes">Successfully updated file suffixes</system:String>
<system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String> <system:String x:Key="wox_plugin_program_suffixes_cannot_empty">File suffixes can't be empty</system:String>
<system:String x:Key="wox_plugin_program_run_as_different_user">Run As Different User</system:String>
<system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String> <system:String x:Key="wox_plugin_program_run_as_administrator">Run As Administrator</system:String>
<system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String> <system:String x:Key="wox_plugin_program_open_containing_folder">Open containing folder</system:String>
<system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String> <system:String x:Key="wox_plugin_program_disable_program">Disable this program from displaying</system:String>

View File

@@ -191,12 +191,12 @@ namespace Wox.Plugin.Program
); );
} }
public static bool StartProcess(ProcessStartInfo info) public static bool StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)
{ {
bool hide; bool hide;
try try
{ {
Process.Start(info); runProcess(info);
hide = true; hide = true;
} }
catch (Exception) catch (Exception)

View File

@@ -320,7 +320,7 @@ namespace Wox.Plugin.Program.Programs
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"), Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
Action = _ => Action = _ =>
{ {
var hide = Main.StartProcess(new ProcessStartInfo(Package.Location)); var hide = Main.StartProcess(Process.Start, new ProcessStartInfo(Package.Location));
return hide; return hide;
}, },
IcoPath = "Images/folder.png" IcoPath = "Images/folder.png"

View File

@@ -6,10 +6,12 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Microsoft.Win32; using Microsoft.Win32;
using Shell; using Shell;
using Wox.Infrastructure; using Wox.Infrastructure;
using Wox.Plugin.Program.Logger; using Wox.Plugin.Program.Logger;
using Wox.Plugin.SharedCommands;
namespace Wox.Plugin.Program.Programs namespace Wox.Plugin.Program.Programs
{ {
@@ -64,7 +66,7 @@ namespace Wox.Plugin.Program.Programs
FileName = FullPath, FileName = FullPath,
WorkingDirectory = ParentDirectory WorkingDirectory = ParentDirectory
}; };
var hide = Main.StartProcess(info); var hide = Main.StartProcess(Process.Start, info);
return hide; return hide;
} }
}; };
@@ -91,6 +93,19 @@ namespace Wox.Plugin.Program.Programs
{ {
var contextMenus = new List<Result> var contextMenus = new List<Result>
{ {
new Result
{
Title = api.GetTranslation("wox_plugin_program_run_as_different_user"),
Action = _ =>
{
var info = FullPath.SetProcessStartInfo(ParentDirectory);
Task.Run(() => Main.StartProcess(ShellCommand.RunAsDifferentUser, info));
return true;
},
IcoPath = "Images/user.png"
},
new Result new Result
{ {
Title = api.GetTranslation("wox_plugin_program_run_as_administrator"), Title = api.GetTranslation("wox_plugin_program_run_as_administrator"),
@@ -102,7 +117,7 @@ namespace Wox.Plugin.Program.Programs
WorkingDirectory = ParentDirectory, WorkingDirectory = ParentDirectory,
Verb = "runas" Verb = "runas"
}; };
var hide = Main.StartProcess(info); var hide = Main.StartProcess(Process.Start, info);
return hide; return hide;
}, },
IcoPath = "Images/cmd.png" IcoPath = "Images/cmd.png"
@@ -112,7 +127,7 @@ namespace Wox.Plugin.Program.Programs
Title = api.GetTranslation("wox_plugin_program_open_containing_folder"), Title = api.GetTranslation("wox_plugin_program_open_containing_folder"),
Action = _ => Action = _ =>
{ {
var hide = Main.StartProcess(new ProcessStartInfo(ParentDirectory)); var hide = Main.StartProcess(Process.Start, new ProcessStartInfo(ParentDirectory));
return hide; return hide;
}, },
IcoPath = "Images/folder.png" IcoPath = "Images/folder.png"

View File

@@ -112,6 +112,9 @@
<None Include="Images\disable.png"> <None Include="Images\disable.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="Images\user.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Languages\en.xaml"> <Content Include="Languages\en.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>

View File

@@ -2,14 +2,65 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Wox.Plugin.SharedCommands namespace Wox.Plugin.SharedCommands
{ {
public static class ShellCommand public static class ShellCommand
{ {
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory="", string arguments = "", string verb = "") public delegate bool EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")] static extern bool EnumThreadWindows(uint threadId, EnumThreadDelegate lpfn, IntPtr lParam);
[DllImport("user32.dll")] static extern int GetWindowText(IntPtr hwnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hwnd);
private static bool containsSecurityWindow;
public static Process RunAsDifferentUser(ProcessStartInfo processStartInfo)
{
processStartInfo.Verb = "RunAsUser";
var process = Process.Start(processStartInfo);
containsSecurityWindow = false;
while (!containsSecurityWindow) // wait for windows to bring up the "Windows Security" dialog
{
CheckSecurityWindow();
Thread.Sleep(25);
}
while (containsSecurityWindow) // while this process contains a "Windows Security" dialog, stay open
{
containsSecurityWindow = false;
CheckSecurityWindow();
Thread.Sleep(50);
}
return process;
}
private static void CheckSecurityWindow()
{
ProcessThreadCollection ptc = Process.GetCurrentProcess().Threads;
for (int i = 0; i < ptc.Count; i++)
EnumThreadWindows((uint)ptc[i].Id, CheckSecurityThread, IntPtr.Zero);
}
private static bool CheckSecurityThread(IntPtr hwnd, IntPtr lParam)
{
if (GetWindowTitle(hwnd) == "Windows Security")
containsSecurityWindow = true;
return true;
}
private static string GetWindowTitle(IntPtr hwnd)
{
StringBuilder sb = new StringBuilder(GetWindowTextLength(hwnd) + 1);
GetWindowText(hwnd, sb, sb.Capacity);
return sb.ToString();
}
public static ProcessStartInfo SetProcessStartInfo(this string fileName, string workingDirectory = "", string arguments = "", string verb = "")
{ {
var info = new ProcessStartInfo var info = new ProcessStartInfo
{ {