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