Created a new way to treat process creation from module interfaces

This commit is contained in:
Noraa Junker
2025-12-11 01:43:04 +01:00
parent 09a79ab692
commit 123d318d6a
12 changed files with 208 additions and 188 deletions

View File

@@ -17,7 +17,7 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed class AdvancedPasteModuleInterface : IPowerToysModule, IDisposable internal sealed class AdvancedPasteModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IDisposable
{ {
public string Name => "AdvancedPaste"; public string Name => "AdvancedPaste";
@@ -33,29 +33,17 @@ namespace RunnerV2.ModuleInterfaces
_ipc.End(); _ipc.End();
_ipc = null; _ipc = null;
} }
ProcessHelper.ScheudleProcessKill("PowerToys.AdvancedPaste");
} }
private TwoWayPipeMessageIPCManaged? _ipc; private TwoWayPipeMessageIPCManaged? _ipc;
private string _ipcName = @"\\.\pipe\PowerToys.AdvancedPaste";
public void Enable() public void Enable()
{ {
if (Process.GetProcessesByName("PowerToys.AdvancedPaste.exe").Length > 0) _ipc = new TwoWayPipeMessageIPCManaged(string.Empty, _ipcName, (_) => { });
{
return;
}
string ipcName = @"\\.\pipe\PowerToys.AdvancedPaste";
_ipc = new TwoWayPipeMessageIPCManaged(string.Empty, ipcName, (_) => { });
_ipc.Start(); _ipc.Start();
if (Shortcuts.Count == 0) PopulateShortcuts();
{
PopulateShortcuts();
}
Process.Start("WinUI3Apps\\PowerToys.AdvancedPaste.exe", $"{Environment.ProcessId} {ipcName}");
} }
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties) public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)
@@ -65,10 +53,7 @@ namespace RunnerV2.ModuleInterfaces
public void PopulateShortcuts() public void PopulateShortcuts()
{ {
if (_ipc is null) _ipc ??= new TwoWayPipeMessageIPCManaged(string.Empty, @"\\.\pipe\PowerToys.AdvancedPaste", (_) => { });
{
_ipc = new TwoWayPipeMessageIPCManaged(string.Empty, @"\\.\pipe\PowerToys.AdvancedPaste", (_) => { });
}
Shortcuts.Clear(); Shortcuts.Clear();
@@ -112,5 +97,13 @@ namespace RunnerV2.ModuleInterfaces
} }
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = []; public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
public override string ProcessPath => "WinUI3Apps\\PowerToys.AdvancedPaste.exe";
public override string ProcessName => "PowerToys.AdvancedPaste";
public override string ProcessArguments => _ipcName;
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument;
} }
} }

View File

@@ -14,7 +14,7 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
public partial class AlwaysOnTopModuleInterface : IPowerToysModule, IDisposable internal sealed partial class AlwaysOnTopModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IDisposable
{ {
public bool Enabled => new SettingsUtils().GetSettings<GeneralSettings>().Enabled.AlwaysOnTop; public bool Enabled => new SettingsUtils().GetSettings<GeneralSettings>().Enabled.AlwaysOnTop;
@@ -22,8 +22,6 @@ namespace RunnerV2.ModuleInterfaces
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAlwaysOnTopEnabledValue(); public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAlwaysOnTopEnabledValue();
private Process? _process;
private InteropEvent? _pinEventWrapper; private InteropEvent? _pinEventWrapper;
public void Disable() public void Disable()
@@ -33,44 +31,22 @@ namespace RunnerV2.ModuleInterfaces
terminateEventWrapper.Dispose(); terminateEventWrapper.Dispose();
_pinEventWrapper?.Dispose(); _pinEventWrapper?.Dispose();
_pinEventWrapper = null; _pinEventWrapper = null;
ProcessHelper.ScheudleProcessKill("PowerToys.AlwaysOnTop");
} }
public void Enable() public void Enable()
{
if (_process?.HasExited == false)
{
return;
}
_pinEventWrapper = new InteropEvent(InteropEvent.AlwaysOnTopPin);
var psi = new ProcessStartInfo
{
FileName = "PowerToys.AlwaysOnTop.exe",
Arguments = Environment.ProcessId.ToString(CultureInfo.InvariantCulture),
UseShellExecute = true,
};
_process = Process.Start(psi);
}
public AlwaysOnTopModuleInterface()
{ {
InitializeHotkey(); InitializeHotkey();
_pinEventWrapper = new InteropEvent(InteropEvent.AlwaysOnTopPin);
} }
private void InitializeHotkey() private void InitializeHotkey()
{ {
Shortcuts.Clear(); Shortcuts.Clear();
Shortcuts.Add((new SettingsUtils().GetSettings<AlwaysOnTopSettings>(Name).Properties.Hotkey.Value, () => Shortcuts.Add((new SettingsUtils().GetSettings<AlwaysOnTopSettings>(Name).Properties.Hotkey.Value, () =>
{
if (!_process?.HasExited ?? false)
{ {
_pinEventWrapper?.Fire(); _pinEventWrapper?.Fire();
} }
})); ));
} }
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties) public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)
@@ -80,9 +56,14 @@ namespace RunnerV2.ModuleInterfaces
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = []; public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
public override string ProcessPath => "PowerToys.AlwaysOnTop.exe";
public override string ProcessName => "PowerToys.AlwaysOnTop";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument | ProcessLaunchOptions.ElevateIfApplicable;
public void Dispose() public void Dispose()
{ {
_process?.Dispose();
_pinEventWrapper?.Dispose(); _pinEventWrapper?.Dispose();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }

View File

@@ -9,10 +9,11 @@ using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper; using PowerToys.GPOWrapper;
using RunnerV2.Helpers; using RunnerV2.Helpers;
using Windows.Media.Capture;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed partial class AwakeModuleInterface : IPowerToysModule, IDisposable internal sealed class AwakeModuleInterface : ProcessModuleAbstractClass, IPowerToysModule
{ {
public string Name => "Awake"; public string Name => "Awake";
@@ -20,38 +21,23 @@ namespace RunnerV2.ModuleInterfaces
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAwakeEnabledValue(); public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAwakeEnabledValue();
private Process? _process; public override string ProcessPath => "PowerToys.Awake.exe";
public override string ProcessName => "PowerToys.Awake";
public override string ProcessArguments => $"--use-pt-config --pid {Environment.ProcessId.ToString(CultureInfo.InvariantCulture)}";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess;
public void Disable() public void Disable()
{ {
InteropEvent terminateEventWrapper = new(InteropEvent.AwakeTerminate); InteropEvent terminateEventWrapper = new(InteropEvent.AwakeTerminate);
terminateEventWrapper.Fire(); terminateEventWrapper.Fire();
terminateEventWrapper.Dispose(); terminateEventWrapper.Dispose();
ProcessHelper.ScheudleProcessKill("PowerToys.Awake");
} }
public void Enable() public void Enable()
{ {
if (_process?.HasExited == false)
{
return;
}
var psi = new ProcessStartInfo
{
FileName = "PowerToys.Awake.exe",
Arguments = $"--use-pt-config --pid {Environment.ProcessId.ToString(CultureInfo.InvariantCulture)}",
UseShellExecute = true,
};
_process = Process.Start(psi);
}
public void Dispose()
{
_process?.Dispose();
GC.SuppressFinalize(this);
} }
} }
} }

View File

@@ -17,7 +17,7 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed partial class ColorPickerModuleInterface : IPowerToysModule, IDisposable internal sealed partial class ColorPickerModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IDisposable
{ {
public string Name => "ColorPicker"; public string Name => "ColorPicker";
@@ -25,8 +25,6 @@ namespace RunnerV2.ModuleInterfaces
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredColorPickerEnabledValue(); public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredColorPickerEnabledValue();
private Process? _process;
private InteropEvent? _showUiEventWrapper; private InteropEvent? _showUiEventWrapper;
public void Disable() public void Disable()
@@ -36,56 +34,40 @@ namespace RunnerV2.ModuleInterfaces
terminateEventWrapper.Dispose(); terminateEventWrapper.Dispose();
_showUiEventWrapper?.Dispose(); _showUiEventWrapper?.Dispose();
_showUiEventWrapper = null; _showUiEventWrapper = null;
ProcessHelper.ScheudleProcessKill("PowerToys.ColorPickerUI");
} }
public void Enable() public void Enable()
{ {
if (_process?.HasExited == false) InitializeShortcuts();
{
return;
}
_showUiEventWrapper = new InteropEvent(InteropEvent.ColorPickerShow); _showUiEventWrapper = new InteropEvent(InteropEvent.ColorPickerShow);
var psi = new ProcessStartInfo
{
FileName = "PowerToys.ColorPickerUI.exe",
Arguments = Environment.ProcessId.ToString(CultureInfo.InvariantCulture),
UseShellExecute = true,
};
_process = Process.Start(psi);
} }
public ColorPickerModuleInterface() private void InitializeShortcuts()
{
InitializeHotkey();
}
private void InitializeHotkey()
{ {
Shortcuts.Clear(); Shortcuts.Clear();
Shortcuts.Add((new SettingsUtils().GetSettings<ColorPickerSettings>(Name).Properties.ActivationShortcut, () => Shortcuts.Add((new SettingsUtils().GetSettings<ColorPickerSettings>(Name).Properties.ActivationShortcut, () =>
{ {
if (!_process?.HasExited ?? false) _showUiEventWrapper?.Fire();
{ }
_showUiEventWrapper?.Fire(); ));
}
}));
} }
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties) public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)
{ {
InitializeHotkey(); InitializeShortcuts();
} }
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = []; public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
public override string ProcessPath => "PowerToys.ColorPickerUI.exe";
public override string ProcessName => "PowerToys.ColorPickerUI";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument;
public void Dispose() public void Dispose()
{ {
_process?.Dispose();
_showUiEventWrapper?.Dispose(); _showUiEventWrapper?.Dispose();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }

View File

@@ -16,7 +16,7 @@ using Windows.ApplicationModel;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed class CommandPaletteModuleInterface : IPowerToysModule internal sealed class CommandPaletteModuleInterface : ProcessModuleAbstractClass, IPowerToysModule
{ {
private const string PackageName = "Microsoft.CommandPalette" private const string PackageName = "Microsoft.CommandPalette"
#if DEBUG #if DEBUG
@@ -30,13 +30,16 @@ namespace RunnerV2.ModuleInterfaces
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredCmdPalEnabledValue(); public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredCmdPalEnabledValue();
public override string ProcessPath => "explorer.exe";
public override string ProcessArguments => "x-cmdpal://background";
public override string ProcessName => string.Empty;
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.UseShellExecute | ProcessLaunchOptions.NeverExit;
public void Disable() public void Disable()
{ {
ProcessHelper.ScheudleProcessKill("Microsoft.CmdPal.UI");
lock (_launchedLock)
{
_launched = false;
}
} }
public void Enable() public void Enable()
@@ -73,64 +76,6 @@ namespace RunnerV2.ModuleInterfaces
Logger.LogError("Command Palette package is not registered after attempting to enable it."); Logger.LogError("Command Palette package is not registered after attempting to enable it.");
return; return;
} }
lock (_launchedLock)
{
if (_launched)
{
return;
}
}
LaunchApp("explorer.exe", "x-cmdpal://background", false);
}
private readonly object _launchedLock = new();
private bool _launched;
// TODO: Implement retry logic for launching the app
/*private static void TryLaunch(string path, string args)
{
int baseDelay = 1000;
int maxAttempts = 9;
int retryCount = 0;
do
{
if (LaunchApp)
}
}*/
private bool LaunchApp(string path, string args, bool elevated)
{
try
{
Process? process = Process.Start(new ProcessStartInfo
{
FileName = path,
CreateNoWindow = true,
UseShellExecute = true,
Verb = elevated ? "runas" : "open",
Arguments = args,
});
if (process is null)
{
Logger.LogError($"Failed to start process for {path} with args {args}");
}
}
catch (Exception ex)
{
Logger.LogError($"Exception occurred while launching app {path} with args {args}", ex);
return false;
}
lock (_launchedLock)
{
_launched = true;
}
return true;
} }
} }
} }

View File

@@ -15,7 +15,7 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed partial class CropAndLockModuleInterface : IPowerToysModule, IDisposable internal sealed partial class CropAndLockModuleInterface : ProcessModuleAbstractClass, IPowerToysModule, IDisposable
{ {
public string Name => "CropAndLock"; public string Name => "CropAndLock";
@@ -33,27 +33,16 @@ namespace RunnerV2.ModuleInterfaces
_reparentEvent.Dispose(); _reparentEvent.Dispose();
_thumbnailEvent.Dispose(); _thumbnailEvent.Dispose();
_terminateEvent.Dispose(); _terminateEvent.Dispose();
ProcessHelper.ScheudleProcessKill("PowerToys.CropAndLock");
} }
public void Enable() public void Enable()
{ {
EnsureLaunched();
_reparentEvent = new(InteropEvent.CropAndLockReparent); _reparentEvent = new(InteropEvent.CropAndLockReparent);
_thumbnailEvent = new(InteropEvent.CropAndLockThumbnail); _thumbnailEvent = new(InteropEvent.CropAndLockThumbnail);
_terminateEvent = new(InteropEvent.CropAndLockTerminate); _terminateEvent = new(InteropEvent.CropAndLockTerminate);
PopulateShortcuts(); PopulateShortcuts();
} }
private void EnsureLaunched()
{
Process[] processes = Process.GetProcessesByName("PowerToys.CropAndLock");
if (processes.Length == 0)
{
Process.Start("PowerToys.CropAndLock.exe", Environment.ProcessId.ToString(CultureInfo.InvariantCulture));
}
}
public void PopulateShortcuts() public void PopulateShortcuts()
{ {
Shortcuts.Clear(); Shortcuts.Clear();
@@ -69,6 +58,12 @@ namespace RunnerV2.ModuleInterfaces
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = []; public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
public override string ProcessPath => "PowerToys.CropAndLock.exe";
public override string ProcessName => "PowerToys.CropAndLock";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument;
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);

View File

@@ -9,7 +9,7 @@ using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed class HostsModuleInterface : IPowerToysModule internal sealed class HostsModuleInterface : ProcessModuleAbstractClass, IPowerToysModule
{ {
public bool Enabled => new SettingsUtils().GetSettingsOrDefault<GeneralSettings>().Enabled.Hosts; public bool Enabled => new SettingsUtils().GetSettingsOrDefault<GeneralSettings>().Enabled.Hosts;
@@ -17,9 +17,14 @@ namespace RunnerV2.ModuleInterfaces
public string Name => "Hosts"; public string Name => "Hosts";
public override string ProcessPath => string.Empty;
public override string ProcessName => "PowerToys.Hosts";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SupressLaunchOnModuleEnabled;
public void Disable() public void Disable()
{ {
ProcessHelper.ScheudleProcessKill("PowerToys.Hosts", 0);
} }
public void Enable() public void Enable()

View File

@@ -10,7 +10,7 @@ using PowerToys.GPOWrapper;
namespace RunnerV2.ModuleInterfaces namespace RunnerV2.ModuleInterfaces
{ {
internal sealed class PowerAccentModuleInterface : IPowerToysModule internal sealed class PowerAccentModuleInterface : ProcessModuleAbstractClass, IPowerToysModule
{ {
public string Name => "PowerAccent"; public string Name => "PowerAccent";
@@ -18,17 +18,18 @@ namespace RunnerV2.ModuleInterfaces
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredQuickAccentEnabledValue(); public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredQuickAccentEnabledValue();
public override string ProcessPath => "PowerToys.PowerAccent.exe";
public override string ProcessName => "PowerToys.PowerAccent";
public override ProcessLaunchOptions LaunchOptions => ProcessLaunchOptions.SingletonProcess | ProcessLaunchOptions.RunnerProcessIdAsFirstArgument;
public void Disable() public void Disable()
{ {
foreach (var process in Process.GetProcessesByName("PowerToys.PowerAccent.exe"))
{
process.Kill();
}
} }
public void Enable() public void Enable()
{ {
Process.Start("PowerToys.PowerAccent.exe", Environment.ProcessId.ToString(CultureInfo.InvariantCulture));
} }
} }
} }

View File

@@ -0,0 +1,114 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PowerToys.GPOWrapper;
using RunnerV2.Helpers;
namespace RunnerV2.ModuleInterfaces
{
internal abstract class ProcessModuleAbstractClass
{
/// <summary>
/// Options for launching a process.
/// </summary>
[Flags]
public enum ProcessLaunchOptions
{
/// <summary>
/// Only a single instance of the process should be running.
/// </summary>
SingletonProcess = 1,
/// <summary>
/// Elevate the process if the current process is elevated.
/// </summary>
ElevateIfApplicable = 2,
/// <summary>
/// Provide the runner process ID as the first argument to the launched process.
/// </summary>
RunnerProcessIdAsFirstArgument = 4,
/// <summary>
/// Indicates that the application should not launch automatically when the specified module is enabled.
/// </summary>
SupressLaunchOnModuleEnabled = 8,
/// <summary>
/// Specifies that the process should be started using the operating system shell.
/// </summary>
UseShellExecute = 16,
/// <summary>
/// Indicates that the process should never exit automatically.
/// </summary>
/// <remarks>Use this value when using a helper process to launch an application like explorer.exe.</remarks>
NeverExit = 32,
}
public abstract string ProcessPath { get; }
public abstract string ProcessName { get; }
public virtual string ProcessArguments { get; } = string.Empty;
public abstract ProcessLaunchOptions LaunchOptions { get; }
public void EnsureLaunched()
{
Process[] processes = Process.GetProcessesByName(ProcessName);
if (processes.Length > 0)
{
return;
}
LaunchProcess();
}
public void LaunchProcess(bool isModuleEnableProcess = false)
{
if (isModuleEnableProcess && LaunchOptions.HasFlag(ProcessLaunchOptions.SupressLaunchOnModuleEnabled))
{
return;
}
if (LaunchOptions.HasFlag(ProcessLaunchOptions.SingletonProcess))
{
Process[] processes = Process.GetProcessesByName(ProcessName);
if (processes.Length > 0)
{
return;
}
}
string arguments = (LaunchOptions.HasFlag(ProcessLaunchOptions.RunnerProcessIdAsFirstArgument) ? Environment.ProcessId.ToString(CultureInfo.InvariantCulture) + (string.IsNullOrEmpty(ProcessArguments) ? string.Empty : " ") : string.Empty) + ProcessArguments;
Process.Start(new ProcessStartInfo()
{
UseShellExecute = LaunchOptions.HasFlag(ProcessLaunchOptions.UseShellExecute),
FileName = ProcessPath,
Arguments = arguments,
Verb = LaunchOptions.HasFlag(ProcessLaunchOptions.ElevateIfApplicable) && ElevationHelper.IsProcessElevated() ? "runas" : "open",
});
}
public void ProcessExit(int msDelay = 500)
{
if (LaunchOptions.HasFlag(ProcessLaunchOptions.NeverExit))
{
return;
}
ProcessHelper.ScheudleProcessKill(ProcessName, msDelay);
}
}
}

View File

@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Drawing; using System.Drawing;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -34,13 +35,13 @@ namespace RunnerV2
public static FrozenSet<IPowerToysModule> ModulesToLoad { get; } = public static FrozenSet<IPowerToysModule> ModulesToLoad { get; } =
[ [
new ColorPickerModuleInterface(),
new AlwaysOnTopModuleInterface(), new AlwaysOnTopModuleInterface(),
new HostsModuleInterface(), new HostsModuleInterface(),
new PowerAccentModuleInterface(), new PowerAccentModuleInterface(),
new AdvancedPasteModuleInterface(), new AdvancedPasteModuleInterface(),
new AwakeModuleInterface(), new AwakeModuleInterface(),
new CmdNotFoundModuleInterface(), new CmdNotFoundModuleInterface(),
new ColorPickerModuleInterface(),
new CommandPaletteModuleInterface(), new CommandPaletteModuleInterface(),
new CropAndLockModuleInterface(), new CropAndLockModuleInterface(),
]; ];
@@ -102,6 +103,12 @@ namespace RunnerV2
try try
{ {
module.Disable(); module.Disable();
if (module is ProcessModuleAbstractClass pmac)
{
pmac.ProcessExit();
}
foreach (var hotkey in module.Hotkeys) foreach (var hotkey in module.Hotkeys)
{ {
HotkeyManager.DisableHotkey(hotkey.Key); HotkeyManager.DisableHotkey(hotkey.Key);
@@ -127,6 +134,11 @@ namespace RunnerV2
if (!LoadedModules.Contains(module)) if (!LoadedModules.Contains(module))
{ {
module.Enable(); module.Enable();
if (module is ProcessModuleAbstractClass pmac)
{
pmac.LaunchProcess(true);
}
LoadedModules.Add(module); LoadedModules.Add(module);
} }
@@ -159,6 +171,11 @@ namespace RunnerV2
{ {
module.Disable(); module.Disable();
if (module is ProcessModuleAbstractClass pmac)
{
pmac.ProcessExit();
}
foreach (var hotkey in module.Hotkeys) foreach (var hotkey in module.Hotkeys)
{ {
HotkeyManager.DisableHotkey(hotkey.Key); HotkeyManager.DisableHotkey(hotkey.Key);

View File

@@ -16,6 +16,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" /> <ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\common\ManagedCsWin32\ManagedCsWin32.csproj" /> <ProjectReference Include="..\..\common\ManagedCsWin32\ManagedCsWin32.csproj" />
<ProjectReference Include="..\..\modules\poweraccent\PowerAccent.UI\PowerAccent.UI.csproj" />
<ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" /> <ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
<ProjectReference Include="..\..\Update\Update.csproj" /> <ProjectReference Include="..\..\Update\Update.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
using System; using System;
using System.Diagnostics;
using ColorPicker.Helpers; using ColorPicker.Helpers;
using ColorPicker.Mouse; using ColorPicker.Mouse;
using ColorPickerUI; using ColorPickerUI;