Skip to content

Support Always Run As Administrator #3573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 116 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 109 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
7549bba
Add administrator mode check
Jack251970 May 22, 2025
369ed86
Add administrator text in tray icon
Jack251970 May 22, 2025
10d379f
Support running application under non-admin mode & Show UAC dialogs w…
Jack251970 May 22, 2025
484f91c
Improve UAC dialog
Jack251970 May 22, 2025
7611b00
Add new restart api
Jack251970 May 22, 2025
d29a5d4
Add setting model
Jack251970 May 22, 2025
40cf413
Add admin support for auto startup
Jack251970 May 22, 2025
fe70a72
Add admin mode configuration in general page
Jack251970 May 22, 2025
0edd626
Remove useless semicolon
Jack251970 May 22, 2025
91f7a4f
Remove useless semicolon
Jack251970 May 22, 2025
902c8f4
Check value changed
Jack251970 May 22, 2025
c5c24ac
Check run level
Jack251970 May 22, 2025
1073061
Remove old before creating new one
Jack251970 May 22, 2025
e9c40e4
Revert "Add new restart api"
Jack251970 May 23, 2025
365ba6a
Code quality
Jack251970 May 23, 2025
eae4a95
Use readonly bool variable
Jack251970 May 23, 2025
52c36ff
Only restart from non-admin to admin & Fix restart as administrator i…
Jack251970 May 23, 2025
35f4fd5
Fix restart as administrator issue
Jack251970 May 23, 2025
eacccf9
Add code comments & Use local function
Jack251970 May 23, 2025
d6462f4
Move restart function to app class
Jack251970 May 23, 2025
479b49d
Throw UnauthorizedAccessException when encountering admin issue
Jack251970 May 23, 2025
c3ec002
Show message box to ask users to restart as administrator when encoun…
Jack251970 May 23, 2025
80c0288
Throw exception when editing highest run level task
Jack251970 May 23, 2025
1b80290
Do not show noticification when run level is correct
Jack251970 May 23, 2025
ca6f077
Merge branch 'dev' into administrator_mode
Jack251970 Jun 3, 2025
ba1ada7
Continue to restart app as administrator if app is run as administrat…
Jack251970 Jun 3, 2025
b2edea4
Improve code quality
Jack251970 Jun 3, 2025
de26abe
Use api functions instead
Jack251970 Jun 3, 2025
23f2489
Force admin restart and fix build issue
Jack251970 Jun 3, 2025
2c1f161
Merge branch 'dev' into administrator_mode
Jack251970 Jun 10, 2025
1a8334f
Add RunAsDesktopUser helper method
Jack251970 Jun 11, 2025
e391c98
Code quality
Jack251970 Jun 11, 2025
100c21a
Add new api to run process as desktop user
Jack251970 Jun 11, 2025
fc53efd
Use new api function to open application
Jack251970 Jun 11, 2025
d77993e
Use new api function to start shell process
Jack251970 Jun 11, 2025
4cf6636
Fix handle close issue
Jack251970 Jun 11, 2025
f1f7309
Add working directory check & Add try-catch
Jack251970 Jun 11, 2025
e8c03c6
Update documents
Jack251970 Jun 11, 2025
ea9ede2
Fix deelevate process running issue
Jack251970 Jun 11, 2025
d13901b
Update work directory correctly
Jack251970 Jun 11, 2025
f9b2be1
Let work directory can be empty
Jack251970 Jun 11, 2025
30deb6d
Fix argument sequence issue
Jack251970 Jun 11, 2025
fb4735f
Fix program deelevate open issue
Jack251970 Jun 11, 2025
b15cece
Fix absolute exe file path issue
Jack251970 Jun 11, 2025
255ca5a
Improve code quality
Jack251970 Jun 11, 2025
433e0fd
Improve uac dialog path
Jack251970 Jun 12, 2025
21e8d92
Add show uac dialog api function
Jack251970 Jun 12, 2025
0d1358f
Add return value for start process api function
Jack251970 Jun 12, 2025
a775323
Improve uac dialog api function
Jack251970 Jun 12, 2025
a3212af
Dynamically find wt.exe
Jack251970 Jun 12, 2025
8b8fcd8
Add IsAdmin
Jack251970 Jun 12, 2025
94f0bb9
Handle command running with administrator mode correctly
Jack251970 Jun 12, 2025
6842fca
Replace IntPtr.Zero with Handle or HWND
Jack251970 Jun 12, 2025
9c6c015
Reflect user intent
Jack251970 Jun 12, 2025
8cfaeea
Return value of RunAsDesktopUser
Jack251970 Jun 12, 2025
61717dc
Ensure SetImageAsync exceptions are handled
Jack251970 Jun 12, 2025
393d106
Fix command line pass issue
Jack251970 Jun 13, 2025
2df7a61
Add command project
Jack251970 Jun 13, 2025
13b5012
Add command executer path
Jack251970 Jun 13, 2025
b8a697c
Fix running issue
Jack251970 Jun 13, 2025
a0ebe29
Improve api function
Jack251970 Jun 13, 2025
3ed8af8
Use new api for program plugin
Jack251970 Jun 13, 2025
5551bdf
Remove uac dialog api function
Jack251970 Jun 13, 2025
2c0210c
Revert unnecessary changes in solution file
Jack251970 Jun 13, 2025
898dbb8
Use new api for uwp package opening
Jack251970 Jun 13, 2025
4ebfb3c
Add api function
Jack251970 Jun 13, 2025
a2be6e0
Use new api for shell plugin
Jack251970 Jun 13, 2025
50a8e88
Use double quotes to fix possible issue
Jack251970 Jun 13, 2025
d56f0a0
Improve process information handler
Jack251970 Jun 13, 2025
dae6f5d
Use WinExe to avoid console ui
Jack251970 Jun 13, 2025
6109504
Add solution assembly information
Jack251970 Jun 13, 2025
8287b33
Fix typo
Jack251970 Jun 13, 2025
be2c59e
Call Win32Helper.IsAdministrator() directly
Jack251970 Jun 13, 2025
d1b4c3c
Merge branch 'administrator_mode' of https://github.com/Flow-Launcher…
Jack251970 Jun 13, 2025
5ddf705
Fix typo
Jack251970 Jun 13, 2025
6843fe0
Fix parameter issue
Jack251970 Jun 13, 2025
680419f
Code quality
Jack251970 Jun 13, 2025
02de9d6
Merge branch 'dev' into administrator_mode
Jack251970 Jun 13, 2025
dd0899f
Check always running as administrator
Jack251970 Jun 13, 2025
1fabe8d
Improve string resource
Jack251970 Jun 13, 2025
def02b3
Improve xml documents
Jack251970 Jun 13, 2025
9d480fc
Quote the executable path to survive spaces & Improve code quality
Jack251970 Jun 13, 2025
f2d3ba7
Combine restart functions to one function
Jack251970 Jun 13, 2025
3a92102
Add new api RestartAppAsAdmin
Jack251970 Jun 13, 2025
d363cad
Improve code quality
Jack251970 Jun 13, 2025
0602143
Change target framework
Jack251970 Jun 13, 2025
7930d57
Add publish file
Jack251970 Jun 13, 2025
8dd9b9c
Publish command project
Jack251970 Jun 13, 2025
11c0eb3
Fix command project publish issue
Jack251970 Jun 13, 2025
7fd3a4a
Merge branch 'dev' into administrator_mode
Jack251970 Jun 13, 2025
a34e404
Change target framework
Jack251970 Jun 14, 2025
ad6d598
Change publish sequence
Jack251970 Jun 14, 2025
764b524
Use exe console type & Add flag support for helper method
Jack251970 Jun 14, 2025
2f3b973
Do not publish command project
Jack251970 Jun 14, 2025
935101c
Change command project output path
Jack251970 Jun 14, 2025
8c81808
Change default value
Jack251970 Jun 14, 2025
e1242ee
Check Process.Start usage
Jack251970 Jun 14, 2025
a76ade8
Merge branch 'dev' into administrator_mode
Jack251970 Jun 14, 2025
e5316a0
Check Process.Start usage
Jack251970 Jun 14, 2025
b6b45d4
Improve code quality
Jack251970 Jun 14, 2025
4df7264
Improve documents
Jack251970 Jun 14, 2025
1dfec7f
Merge branch 'dev' into administrator_mode
Jack251970 Jun 14, 2025
39de484
Merge branch 'administrator_mode' of https://github.com/Flow-Launcher…
Jack251970 Jun 14, 2025
44b25b4
Prefer injected Context over static Main.Context
Jack251970 Jun 15, 2025
d1daf51
Merge branch 'dev' into administrator_mode
Jack251970 Jun 15, 2025
478ba29
Change target framework to remove dll files
Jack251970 Jun 15, 2025
9119998
Build command project after main project
Jack251970 Jun 15, 2025
3493446
Support createNoWindow for start process api
Jack251970 Jun 15, 2025
7ea76b8
Support administrator handling for ShellRun api function
Jack251970 Jun 15, 2025
721bb98
Handle create no window parameter in command exe
Jack251970 Jun 15, 2025
81667d0
Fix ui issue
Jack251970 Jun 15, 2025
10567fd
Merge branch 'dev' into administrator_mode
Jack251970 Jun 16, 2025
4862a2d
Check if the application is running as administrator ealier
Jack251970 Jun 16, 2025
4416efe
Revert "Check if the application is running as administrator ealier"
Jack251970 Jun 16, 2025
71af5ef
Check if the application is running as administrator ealier
Jack251970 Jun 16, 2025
48ed897
Merge branch 'dev' into administrator_mode
Jack251970 Jun 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Flow.Launcher.Command/Flow.Launcher.Command.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Flow.Launcher.Command</RootNamespace>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<ApplicationIcon>app.ico</ApplicationIcon>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Output\Debug\Command\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>true</UseVSHostingProcess>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Output\Release\Command\</OutputPath>
<DefineConstants>TRACE;RELEASE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>

<ItemGroup>
<Content Include="app.ico" />
</ItemGroup>

<ItemGroup>
<Compile Include="..\SolutionAssemblyInfo.cs" Link="Properties\SolutionAssemblyInfo.cs" />
</ItemGroup>

</Project>
123 changes: 123 additions & 0 deletions Flow.Launcher.Command/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using System.Diagnostics;

namespace Flow.Launcher.Command;

internal static class Program
{
[STAThread]
private static int Main(string[] args)
{
if (args.Length == 0) return -1;

// Start process with arguments
// Usage: Flow.Launcher.Command -StartProcess -FileName <file> -WorkingDirectory <directory> -Arguments <args> -UseShellExecute <true|false> -Verb <verb>
if (args[0] == @"-StartProcess")
{
var fileName = string.Empty;
var workingDirectory = Environment.CurrentDirectory;
var argumentList = new List<string>();
var useShellExecute = true;
var verb = string.Empty;
var isArguments = false;

for (int i = 1; i < args.Length; i++)
{
switch (args[i])
{
case "-FileName":
if (i + 1 < args.Length)
fileName = args[++i];
isArguments = false;
break;

case "-WorkingDirectory":

Check warning on line 33 in Flow.Launcher.Command/Program.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`orking` is not a recognized word. (unrecognized-spelling)
if (i + 1 < args.Length)
workingDirectory = args[++i];
isArguments = false;
break;

case "-Arguments":
if (i + 1 < args.Length)
argumentList.Add(args[++i]);
isArguments = true;
break;

case "-UseShellExecute":
if (i + 1 < args.Length && bool.TryParse(args[++i], out bool useShell))
useShellExecute = useShell;
isArguments = false;
break;

case "-Verb":
if (i + 1 < args.Length)
verb = args[++i];
isArguments = false;
break;

default:
if (isArguments)
argumentList.Add(args[i]);
else
Console.WriteLine($"Unknown parameter: {args[i]}");
break;
}
}

if (string.IsNullOrEmpty(fileName))
{
Console.WriteLine("Error: -FileName is required.");
return -2;
}

try
{
ProcessStartInfo info;
if (argumentList.Count == 0)
{
info = new ProcessStartInfo
{
FileName = fileName,
WorkingDirectory = workingDirectory,
UseShellExecute = useShellExecute,
Verb = verb
};
}
else if (argumentList.Count == 1)
{
info = new ProcessStartInfo
{
FileName = fileName,
WorkingDirectory = workingDirectory,
Arguments = argumentList[0],
UseShellExecute = useShellExecute,
Verb = verb
};
}
else
{
info = new ProcessStartInfo
{
FileName = fileName,
WorkingDirectory = workingDirectory,
UseShellExecute = useShellExecute,
Verb = verb
};
foreach (var arg in argumentList)
{
info.ArgumentList.Add(arg);
}
}
Process.Start(info)?.Dispose();
Console.WriteLine("Success.");
return 0;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return -3;
}
}

return -4;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<PublishDir>..\Output\Release\</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun>False</PublishReadyToRun>
<PublishTrimmed>False</PublishTrimmed>
</PropertyGroup>
</Project>
Binary file added Flow.Launcher.Command/app.ico
Binary file not shown.
4 changes: 2 additions & 2 deletions Flow.Launcher.Core/Configuration/Portable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
API.ShowMsgBox("Flow Launcher needs to restart to finish disabling portable mode, " +
"after the restart your portable data profile will be deleted and roaming data profile kept");

UpdateManager.RestartApp(Constant.ApplicationFileName);
API.RestartApp();
}
catch (Exception e)
{
Expand All @@ -62,7 +62,7 @@
{
MoveUserDataFolder(DataLocation.RoamingDataPath, DataLocation.PortableDataPath);
#if !DEBUG
// Remove shortcuts and uninstaller are not required in debug mode,

Check warning on line 65 in Flow.Launcher.Core/Configuration/Portable.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`uninstaller` is not a recognized word. (unrecognized-spelling)
// otherwise will delete the actual installed production version
RemoveShortcuts();
RemoveUninstallerEntry();
Expand All @@ -72,7 +72,7 @@
API.ShowMsgBox("Flow Launcher needs to restart to finish enabling portable mode, " +
"after the restart your roaming data profile will be deleted and portable data profile kept");

UpdateManager.RestartApp(Constant.ApplicationFileName);
API.RestartApp();
}
catch (Exception e)
{
Expand Down
6 changes: 3 additions & 3 deletions Flow.Launcher.Core/Updater.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Infrastructure;
using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using JetBrains.Annotations;
using Squirrel;

Expand Down Expand Up @@ -89,7 +89,7 @@

if (_api.ShowMsgBox(newVersionTips, _api.GetTranslation("update_flowlauncher_new_update"), MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
UpdateManager.RestartApp(Constant.ApplicationFileName);
_api.RestartApp();
}
}
catch (Exception e)
Expand Down Expand Up @@ -138,7 +138,7 @@
var latest = releases.Where(r => !r.Prerelease).OrderByDescending(r => r.PublishedAt).First();
var latestUrl = latest.HtmlUrl.Replace("/tag/", "/download/");

var client = new WebClient

Check warning on line 141 in Flow.Launcher.Core/Updater.cs

View workflow job for this annotation

GitHub Actions / build

'WebClient.WebClient()' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' (https://aka.ms/dotnet-warnings/SYSLIB0014)
{
Proxy = Http.WebProxy
};
Expand Down
1 change: 1 addition & 0 deletions Flow.Launcher.Infrastructure/Constant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static class Constant
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
public static readonly string ProgramDirectory = Directory.GetParent(Assembly.Location.NonNull()).ToString();
public static readonly string ExecutablePath = Path.Combine(ProgramDirectory, FlowLauncher + ".exe");
public static readonly string CommandExecutablePath = Path.Combine(ProgramDirectory, "Command", "Flow.Launcher.Command.exe");
public static readonly string ApplicationDirectory = Directory.GetParent(ProgramDirectory).ToString();
public static readonly string RootDirectory = Directory.GetParent(ApplicationDirectory).ToString();

Expand Down
2 changes: 1 addition & 1 deletion Flow.Launcher.Infrastructure/Http/Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ public static async Task<string> GetStringAsync(string url, CancellationToken to
Log.Debug(ClassName, $"Url <{url}>");
return await client.GetStringAsync(url, token);
}
catch (System.Exception e)
catch (System.Exception)
{
return string.Empty;
}
Expand Down
14 changes: 14 additions & 0 deletions Flow.Launcher.Infrastructure/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,17 @@ LOCALE_TRANSIENT_KEYBOARD4
SHParseDisplayName
SHOpenFolderAndSelectItems
CoTaskMemFree

OpenProcessToken
GetCurrentProcess
LookupPrivilegeValue
SE_INCREASE_QUOTA_NAME
CloseHandle
TOKEN_PRIVILEGES
AdjustTokenPrivileges
GetShellWindow
GetWindowThreadProcessId
OpenProcess
GetProcessId
DuplicateTokenEx
CreateProcessWithTokenW
2 changes: 2 additions & 0 deletions Flow.Launcher.Infrastructure/UserSettings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,8 @@ public bool HideNotifyIcon
public bool LeaveCmdOpen { get; set; }
public bool HideWhenDeactivated { get; set; } = true;

public bool AlwaysRunAsAdministrator { get; set; } = false;

private bool _showAtTopmost = false;
public bool ShowAtTopmost
{
Expand Down
Loading
Loading