From 100c21a83e33c7bab87745b184863f7c7ba639b6 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Wed, 11 Jun 2025 16:02:24 +0800
Subject: [PATCH] Add new api to run process as desktop user
---
Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs | 12 ++++++++
Flow.Launcher/PublicAPIInstance.cs | 29 +++++++++++++++++--
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
index 76c7a4911..13564626b 100644
--- a/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
+++ b/Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs
@@ -580,5 +580,17 @@ namespace Flow.Launcher.Plugin
///
/// The time taken to execute the method in milliseconds
public Task StopwatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "");
+
+ ///
+ /// Start a process with the given file path and arguments
+ ///
+ ///
+ /// It can help to start a deelevated process when Flow is running as administrator.
+ ///
+ /// File path of the process to start. It can be an executable file or a script file
+ /// Working directory of the process. If not specified, the current directory will be used
+ /// Optional arguments to pass to the process. If not specified, no arguments will be passed
+ /// Whether to run the process as administrator
+ public void StartProcess(string filePath, string workingDirectory, string arguments = "", bool runAsAdmin = false);
}
}
diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs
index 694b13cdd..3f003e660 100644
--- a/Flow.Launcher/PublicAPIInstance.cs
+++ b/Flow.Launcher/PublicAPIInstance.cs
@@ -14,21 +14,21 @@ using System.Windows;
using System.Windows.Media;
using CommunityToolkit.Mvvm.DependencyInjection;
using Flow.Launcher.Core;
+using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Core.Resource;
-using Flow.Launcher.Core.ExternalPlugins;
using Flow.Launcher.Core.Storage;
using Flow.Launcher.Helper;
using Flow.Launcher.Infrastructure;
-using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Hotkey;
+using Flow.Launcher.Infrastructure.Http;
using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Storage;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;
-using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.Plugin.SharedCommands;
+using Flow.Launcher.Plugin.SharedModels;
using Flow.Launcher.ViewModel;
using JetBrains.Annotations;
using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch;
@@ -577,6 +577,29 @@ namespace Flow.Launcher
public Task StopwatchLogInfoAsync(string className, string message, Func action, [CallerMemberName] string methodName = "") =>
Stopwatch.InfoAsync(className, message, action, methodName);
+ public void StartProcess(string filePath, string workingDirectory, string arguments = "", bool runAsAdmin = false)
+ {
+ // Deelevate process if it is running as administrator
+ if (Win32Helper.IsAdministrator() && !runAsAdmin)
+ {
+ Win32Helper.RunAsDesktopUser(filePath, workingDirectory, arguments, out var errorInfo);
+ if (!string.IsNullOrEmpty(errorInfo))
+ {
+ LogError(ClassName, $"Failed to start process {filePath} with error: {errorInfo}");
+ }
+ }
+
+ var info = new ProcessStartInfo
+ {
+ FileName = filePath,
+ WorkingDirectory = workingDirectory,
+ Arguments = arguments,
+ UseShellExecute = true,
+ Verb = runAsAdmin ? "runas" : "",
+ };
+ Process.Start(info)?.Dispose();
+ }
+
#endregion
#region Private Methods