diff --git a/src/RunnerV2/RunnerV2/Helpers/PackageHelper.cs b/src/RunnerV2/RunnerV2/Helpers/PackageHelper.cs
index 2c277b84ae..656a4d47d3 100644
--- a/src/RunnerV2/RunnerV2/Helpers/PackageHelper.cs
+++ b/src/RunnerV2/RunnerV2/Helpers/PackageHelper.cs
@@ -72,7 +72,13 @@ namespace RunnerV2.Helpers
return [.. matchedFiles];
}
- internal static bool RegisterPackage(string packagePath, string[] dependencies)
+ ///
+ /// Installs the specified appx package along with its dependencies.
+ ///
+ /// Path to the package
+ /// Array of dependency package paths
+ /// True if the installation was successful, false otherwise
+ internal static bool InstallPackage(string packagePath, string[] dependencies)
{
Logger.LogInfo("Starting package install of package \"" + packagePath + "\"");
PackageManager packageManager = new();
@@ -129,6 +135,11 @@ namespace RunnerV2.Helpers
return false;
}
+ ///
+ /// Checks if the package specified by the given path is already installed and satisfies the required version.
+ ///
+ /// Path to the package.
+ /// True if the package is already installed and satisfies the required version, false otherwise.
private static bool IsPackageSatisfied(string packagePath)
{
if (!GetPackageNameAndVersionFromAppx(packagePath, out string name, out PackageVersion version))
@@ -153,6 +164,13 @@ namespace RunnerV2.Helpers
return false;
}
+ ///
+ /// Gets the package name and version from the specified appx package file.
+ ///
+ /// Path to the package file.
+ /// Output parameter for the package name.
+ /// Output parameter for the package version.
+ /// True if the package name and version were successfully retrieved, false otherwise.
private static bool GetPackageNameAndVersionFromAppx(string packagePath, out string name, out PackageVersion packageVersion)
{
// Todo: Implement this without interop if possible
diff --git a/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs b/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs
index 072d2b4ba6..d01e3997d3 100644
--- a/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs
+++ b/src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs
@@ -10,16 +10,17 @@ using System.IO;
using System.IO.Pipelines;
using System.Linq;
using System.Text.Json;
-using System.Threading;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.Interop;
using RunnerV2.ModuleInterfaces;
using Update;
-using Windows.Media.Devices;
namespace RunnerV2.Helpers
{
+ ///
+ /// This class provides helper methods to interact with the PowerToys Settings window.
+ ///
internal static class SettingsHelper
{
private static readonly SettingsUtils _settingsUtils = new();
diff --git a/src/RunnerV2/RunnerV2/ModuleInterfaces/CommandPaletteModuleInterface.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/CommandPaletteModuleInterface.cs
index 67d5037832..796ea662a8 100644
--- a/src/RunnerV2/RunnerV2/ModuleInterfaces/CommandPaletteModuleInterface.cs
+++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/CommandPaletteModuleInterface.cs
@@ -59,7 +59,7 @@ namespace RunnerV2.ModuleInterfaces
if (msixFiles.Length > 0)
{
- if (!PackageHelper.RegisterPackage(msixFiles[0], dependencies))
+ if (!PackageHelper.InstallPackage(msixFiles[0], dependencies))
{
Logger.LogError("Failed to register Command Palette package.");
}
diff --git a/src/RunnerV2/RunnerV2/ModuleInterfaces/ProcessModuleAbstractClass.cs b/src/RunnerV2/RunnerV2/ModuleInterfaces/ProcessModuleAbstractClass.cs
index e6846277c8..d2fc35949f 100644
--- a/src/RunnerV2/RunnerV2/ModuleInterfaces/ProcessModuleAbstractClass.cs
+++ b/src/RunnerV2/RunnerV2/ModuleInterfaces/ProcessModuleAbstractClass.cs
@@ -15,6 +15,9 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces
{
+ ///
+ /// Base abstract class for modules that launch and manage external processes.
+ ///
internal abstract class ProcessModuleAbstractClass
{
///
@@ -55,14 +58,36 @@ namespace RunnerV2.ModuleInterfaces
NeverExit = 32,
}
+ ///
+ /// Gets the relative or absolute path to the process executable.
+ ///
public abstract string ProcessPath { get; }
+ ///
+ /// Gets the name of the process without the .exe extension.
+ ///
+ ///
+ /// Has no effect if the has the flag set.
+ ///
public abstract string ProcessName { get; }
+ ///
+ /// Gets the arguments to pass to the process on launch.
+ ///
+ ///
+ /// If not overridden, no arguments are passed.
+ /// If the has the flag is set, the runner process ID is prepended to these arguments.
+ ///
public virtual string ProcessArguments { get; } = string.Empty;
+ ///
+ /// Gets the options used to configure how the process is launched.
+ ///
public abstract ProcessLaunchOptions LaunchOptions { get; }
+ ///
+ /// Ensures that atleast one process is launched. If the process is already running, does nothing.
+ ///
public void EnsureLaunched()
{
Process[] processes = Process.GetProcessesByName(ProcessName);
@@ -74,6 +99,10 @@ namespace RunnerV2.ModuleInterfaces
LaunchProcess();
}
+ ///
+ /// Launches the process with the specified options.
+ ///
+ /// Specifies if the class is currently calling this function as part of a module startup
public void LaunchProcess(bool isModuleEnableProcess = false)
{
if (isModuleEnableProcess && LaunchOptions.HasFlag(ProcessLaunchOptions.SupressLaunchOnModuleEnabled))
@@ -101,14 +130,20 @@ namespace RunnerV2.ModuleInterfaces
});
}
- public void ProcessExit(int msDelay = 500)
+ ///
+ /// Schedules all processes with the specified .
+ ///
+ ///
+ /// If the has the flag set, this function does nothing.
+ ///
+ public void ProcessExit()
{
if (LaunchOptions.HasFlag(ProcessLaunchOptions.NeverExit))
{
return;
}
- ProcessHelper.ScheudleProcessKill(ProcessName, msDelay);
+ ProcessHelper.ScheudleProcessKill(ProcessName);
}
}
}
diff --git a/src/RunnerV2/RunnerV2/NativeMethods.cs b/src/RunnerV2/RunnerV2/NativeMethods.cs
index bbc0def459..ca4d910162 100644
--- a/src/RunnerV2/RunnerV2/NativeMethods.cs
+++ b/src/RunnerV2/RunnerV2/NativeMethods.cs
@@ -190,11 +190,6 @@ namespace RunnerV2
public string LpszClassName;
}
- [DllImport("user32.dll", SetLastError = true)]
- internal static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
-
- internal delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
-
[DllImport("Advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptorW(
@@ -233,22 +228,6 @@ namespace RunnerV2
[DllImport("user32.dll")]
internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
- public const int COINIT_MULTITHREADED = 0x0;
-
- [LibraryImport("ole32.dll")]
- public static partial int CoInitializeEx(IntPtr pvReserved, int dwCoInit);
-
- [LibraryImport("ole32.dll")]
- public static partial void CoUninitialize();
-
- [DllImport("Shlwapi.dll")]
- public static extern IntPtr SHCreateStreamOnFileEx(
- [MarshalAs(UnmanagedType.LPWStr)] string pszFile,
- uint grfMode,
- [MarshalAs(UnmanagedType.Bool)]bool fCreate,
- IntPtr pstmTemplate,
- out IStream stream);
-
[DllImport("PowerToys.Interop.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern bool GetPackageNameAndVersionFromAppx(
[MarshalAs(UnmanagedType.LPWStr)] string appxPath,
diff --git a/src/RunnerV2/RunnerV2/Program.cs b/src/RunnerV2/RunnerV2/Program.cs
index 1444e2ef90..43f1899b2e 100644
--- a/src/RunnerV2/RunnerV2/Program.cs
+++ b/src/RunnerV2/RunnerV2/Program.cs
@@ -111,7 +111,7 @@ internal sealed class Program
tempGeneralSettings.IsElevated = isElevated;
_settingsUtils.SaveSettings(tempGeneralSettings.ToJsonString());
- _ = Runner.Run(afterInitializationAction);
+ Runner.Run(afterInitializationAction);
break;
default:
ElevationHelper.RestartScheduled = ElevationHelper.RestartScheduledMode.RestartElevated;
@@ -121,6 +121,11 @@ internal sealed class Program
ElevationHelper.RestartIfScheudled();
}
+ ///
+ /// Returns whether the application should run in a special mode based on the provided arguments.
+ ///
+ /// The arguments passed to
+ /// The the app should run in.
private static SpecialMode ShouldRunInSpecialMode(string[] args)
{
if (args.Length > 0 && args[0].StartsWith("powertoys://", StringComparison.InvariantCultureIgnoreCase))
@@ -137,6 +142,9 @@ internal sealed class Program
return SpecialMode.None;
}
+ ///
+ /// Starts the update process for PowerToys.
+ ///
private static void UpdateNow()
{
Process.Start(new ProcessStartInfo()
diff --git a/src/RunnerV2/RunnerV2/Runner.cs b/src/RunnerV2/RunnerV2/Runner.cs
index 1f765e3f07..ea72e9006e 100644
--- a/src/RunnerV2/RunnerV2/Runner.cs
+++ b/src/RunnerV2/RunnerV2/Runner.cs
@@ -27,12 +27,21 @@ namespace RunnerV2
{
internal static partial class Runner
{
+ ///
+ /// Gets the window handle for the Runner main window that hosts the tray icon and receives system messages.
+ ///
public static nint RunnerHwnd { get; private set; }
private const string TrayWindowClassName = "pt_tray_icon_window_class";
+ ///
+ /// Gets all the currently loaded modules.
+ ///
public static List LoadedModules { get; } = [];
+ ///
+ /// Gets the list of all available PowerToys modules.
+ ///
public static FrozenSet ModulesToLoad { get; } =
[
new ColorPickerModuleInterface(),
@@ -46,7 +55,11 @@ namespace RunnerV2
new CropAndLockModuleInterface(),
];
- internal static bool Run(Action afterInitializationAction)
+ ///
+ /// Runs the main message loop for Runner.
+ ///
+ /// A function to execute after initialization.
+ internal static void Run(Action afterInitializationAction)
{
Logger.LogInfo("Runner started");
@@ -65,12 +78,13 @@ namespace RunnerV2
afterInitializationAction();
MessageLoop();
-
- return true;
}
private static readonly uint _taskbarCreatedMessage = RegisterWindowMessageW("TaskbarCreated");
+ ///
+ /// The main message loop that processes Windows messages.
+ ///
[STAThread]
private static void MessageLoop()
{
@@ -91,6 +105,9 @@ namespace RunnerV2
Close();
}
+ ///
+ /// Closes Runner and all loaded modules.
+ ///
[DoesNotReturn]
internal static void Close()
{
@@ -123,6 +140,10 @@ namespace RunnerV2
Environment.Exit(0);
}
+ ///
+ /// Toggles the state of a module based on its enabled property and GPO rules.
+ ///
+ /// The module to toggle
public static void ToggleModuleStateBasedOnEnabledProperty(IPowerToysModule module)
{
try
@@ -194,6 +215,9 @@ namespace RunnerV2
}
}
+ ///
+ /// Initializes the tray window to receive system messages.
+ ///
[STAThread]
private static void InitializeTrayWindow()
{
@@ -238,6 +262,9 @@ namespace RunnerV2
}
}
+ ///
+ /// Handles Windows messages sent to the tray window.
+ ///
private static IntPtr HandleMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch (msg)