mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
Add Keyboard Hook mechanism
This commit is contained in:
61
src/RunnerV2/RunnerV2/Helpers/COMUtils.cs
Normal file
61
src/RunnerV2/RunnerV2/Helpers/COMUtils.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RunnerV2.Helpers
|
||||
{
|
||||
internal static class COMUtils
|
||||
{
|
||||
public static void InitializeCOMSecurity(string securityDescriptor)
|
||||
{
|
||||
if (!NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||
securityDescriptor,
|
||||
1,
|
||||
out IntPtr pSD,
|
||||
out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint absoluteSDSize = 0;
|
||||
uint daclSize = 0;
|
||||
uint groupSize = 0;
|
||||
uint ownerSize = 0;
|
||||
uint saclSize = 0;
|
||||
|
||||
if (!NativeMethods.MakeAbsoluteSD(pSD, IntPtr.Zero, ref absoluteSDSize, IntPtr.Zero, ref daclSize, IntPtr.Zero, ref saclSize, IntPtr.Zero, ref ownerSize, IntPtr.Zero, ref groupSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IntPtr absoluteSD = Marshal.AllocHGlobal((int)absoluteSDSize);
|
||||
IntPtr dacl = Marshal.AllocHGlobal((int)daclSize);
|
||||
IntPtr sacl = Marshal.AllocHGlobal((int)saclSize);
|
||||
IntPtr owner = Marshal.AllocHGlobal((int)ownerSize);
|
||||
IntPtr group = Marshal.AllocHGlobal((int)groupSize);
|
||||
|
||||
if (!NativeMethods.MakeAbsoluteSD(pSD, absoluteSD, ref absoluteSDSize, dacl, ref daclSize, sacl, ref saclSize, owner, ref ownerSize, group, ref groupSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ = NativeMethods.CoInitializeSecurity(
|
||||
absoluteSD,
|
||||
-1,
|
||||
IntPtr.Zero,
|
||||
IntPtr.Zero,
|
||||
6, // RPC_C_AUTHN_LEVEL_PKT_PRIVACY
|
||||
2, // RPC_C_IMP_LEVEL_IDENTIFY
|
||||
IntPtr.Zero,
|
||||
64 | 4096, // EOAC_DYNAMIC_CLOAKING | EOAC_DISABLE_AAA
|
||||
IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
169
src/RunnerV2/RunnerV2/Helpers/CentralizedKeyboardHookManager.cs
Normal file
169
src/RunnerV2/RunnerV2/Helpers/CentralizedKeyboardHookManager.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Windows.System;
|
||||
|
||||
namespace RunnerV2.Helpers
|
||||
{
|
||||
internal static class CentralizedKeyboardHookManager
|
||||
{
|
||||
private static readonly UIntPtr _ignoreKeyEventFlag = 0x5555;
|
||||
|
||||
private static readonly Dictionary<string, List<(HotkeySettings HotkeySettings, Action Action)>> _keyboardHooks = [];
|
||||
|
||||
private static HotkeySettingsControlHook _hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag);
|
||||
|
||||
private static void OnKeyDown(int key)
|
||||
{
|
||||
switch ((VirtualKey)key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
case VirtualKey.LeftControl:
|
||||
case VirtualKey.RightControl:
|
||||
_ctrlState = true;
|
||||
break;
|
||||
case VirtualKey.Menu:
|
||||
case VirtualKey.LeftMenu:
|
||||
case VirtualKey.RightMenu:
|
||||
_altState = true;
|
||||
break;
|
||||
case VirtualKey.Shift:
|
||||
case VirtualKey.LeftShift:
|
||||
case VirtualKey.RightShift:
|
||||
_shiftState = true;
|
||||
break;
|
||||
case VirtualKey.LeftWindows:
|
||||
case VirtualKey.RightWindows:
|
||||
_winState = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyDown);
|
||||
}
|
||||
|
||||
private static void OnKeyUp(int key)
|
||||
{
|
||||
switch ((VirtualKey)key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
case VirtualKey.LeftControl:
|
||||
case VirtualKey.RightControl:
|
||||
_ctrlState = false;
|
||||
break;
|
||||
case VirtualKey.Menu:
|
||||
case VirtualKey.LeftMenu:
|
||||
case VirtualKey.RightMenu:
|
||||
_altState = false;
|
||||
break;
|
||||
case VirtualKey.Shift:
|
||||
case VirtualKey.LeftShift:
|
||||
case VirtualKey.RightShift:
|
||||
_shiftState = false;
|
||||
break;
|
||||
case VirtualKey.LeftWindows:
|
||||
case VirtualKey.RightWindows:
|
||||
_winState = false;
|
||||
break;
|
||||
default:
|
||||
OnKeyboardEvent(new HotkeySettings
|
||||
{
|
||||
Code = key,
|
||||
Ctrl = _ctrlState,
|
||||
Alt = _altState,
|
||||
Shift = _shiftState,
|
||||
Win = _winState,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
SendSingleKeyboardInput((short)key, (uint)NativeKeyboardHelper.KeyEventF.KeyUp);
|
||||
}
|
||||
|
||||
private static bool _ctrlState;
|
||||
private static bool _altState;
|
||||
private static bool _shiftState;
|
||||
private static bool _winState;
|
||||
|
||||
private static bool _isActive;
|
||||
|
||||
private static bool IsActive()
|
||||
{
|
||||
return _isActive;
|
||||
}
|
||||
|
||||
public static void AddKeyboardHook(string moduleName, HotkeySettings hotkeySettings, Action action)
|
||||
{
|
||||
#pragma warning disable CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method
|
||||
if (!_keyboardHooks.ContainsKey(moduleName))
|
||||
{
|
||||
_keyboardHooks[moduleName] = [];
|
||||
}
|
||||
#pragma warning restore CA1854 // Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method
|
||||
|
||||
_keyboardHooks[moduleName].Add((hotkeySettings, action));
|
||||
}
|
||||
|
||||
public static void RemoveAllHooksFromModule(string moduleName)
|
||||
{
|
||||
_keyboardHooks.Remove(moduleName);
|
||||
}
|
||||
|
||||
private static void OnKeyboardEvent(HotkeySettings pressedHotkey)
|
||||
{
|
||||
foreach (var moduleHooks in _keyboardHooks.Values)
|
||||
{
|
||||
foreach (var (hotkeySettings, action) in moduleHooks)
|
||||
{
|
||||
if (hotkeySettings == pressedHotkey)
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
if (_hotkeySettingsControlHook.GetDisposedState())
|
||||
{
|
||||
_hotkeySettingsControlHook = new(OnKeyDown, OnKeyUp, IsActive, (_, specialFlags) => specialFlags != _ignoreKeyEventFlag);
|
||||
}
|
||||
|
||||
_isActive = true;
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
_isActive = false;
|
||||
_hotkeySettingsControlHook.Dispose();
|
||||
}
|
||||
|
||||
// Function to send a single key event to the system which would be ignored by the hotkey control.
|
||||
private static void SendSingleKeyboardInput(short keyCode, uint keyStatus)
|
||||
{
|
||||
NativeKeyboardHelper.INPUT inputShift = new()
|
||||
{
|
||||
type = NativeKeyboardHelper.INPUTTYPE.INPUT_KEYBOARD,
|
||||
data = new NativeKeyboardHelper.InputUnion
|
||||
{
|
||||
ki = new NativeKeyboardHelper.KEYBDINPUT
|
||||
{
|
||||
wVk = keyCode,
|
||||
dwFlags = keyStatus,
|
||||
dwExtraInfo = _ignoreKeyEventFlag,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
NativeKeyboardHelper.INPUT[] inputs = [inputShift];
|
||||
|
||||
_ = NativeMethods.SendInput(1, inputs, NativeKeyboardHelper.INPUT.Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ using System.Threading;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using PowerToys.Interop;
|
||||
using RunnerV2.ModuleInterfaces;
|
||||
using Update;
|
||||
using Windows.Media.Devices;
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// 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.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
|
||||
using PowerToys.GPOWrapper;
|
||||
using PowerToys.Interop;
|
||||
|
||||
namespace RunnerV2.ModuleInterfaces
|
||||
{
|
||||
internal sealed class AdvancedPasteModuleInterface : IPowerToysModule, IDisposable
|
||||
{
|
||||
public string Name => "AdvancedPaste";
|
||||
|
||||
public bool Enabled => new SettingsUtils().GetSettings<GeneralSettings>().Enabled.AdvancedPaste;
|
||||
|
||||
public GpoRuleConfigured GpoRuleConfigured => GPOWrapper.GetConfiguredAdvancedPasteEnabledValue();
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
if (_ipc != null)
|
||||
{
|
||||
_ipc.Send("TerminateApp");
|
||||
_ipc.End();
|
||||
_ipc = null;
|
||||
}
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(500);
|
||||
foreach (var process in Process.GetProcessesByName("PowerToys.AdvancedPaste.exe"))
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private TwoWayPipeMessageIPCManaged? _ipc;
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
if (Process.GetProcessesByName("PowerToys.AdvancedPaste.exe").Length > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string ipcName = @"\\.\pipe\PowerToys.AdvancedPaste";
|
||||
_ipc = new TwoWayPipeMessageIPCManaged(string.Empty, ipcName, (_) => { });
|
||||
_ipc.Start();
|
||||
|
||||
if (Shortcuts.Count == 0)
|
||||
{
|
||||
PopulateShortcuts();
|
||||
}
|
||||
|
||||
Process.Start("WinUI3Apps\\PowerToys.AdvancedPaste.exe", $"{Environment.ProcessId} {ipcName}");
|
||||
}
|
||||
|
||||
public void OnSettingsChanged()
|
||||
{
|
||||
PopulateShortcuts();
|
||||
}
|
||||
|
||||
public void PopulateShortcuts()
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(_ipc);
|
||||
|
||||
Shortcuts.Clear();
|
||||
|
||||
AdvancedPasteSettings settings = new SettingsUtils().GetSettings<AdvancedPasteSettings>();
|
||||
Shortcuts.Add((settings.Properties.AdvancedPasteUIShortcut, () =>
|
||||
_ipc.Send("ShowUI")
|
||||
));
|
||||
Shortcuts.Add((settings.Properties.PasteAsPlainTextShortcut, TryToPasteAsPlainText));
|
||||
Shortcuts.Add((settings.Properties.PasteAsMarkdownShortcut, () => _ipc.Send("PasteMarkdown")));
|
||||
Shortcuts.Add((settings.Properties.PasteAsJsonShortcut, () => _ipc.Send("PasteJson")));
|
||||
|
||||
HotkeyAccessor[] hotkeyAccessors = settings.GetAllHotkeyAccessors();
|
||||
for (int i = 4; i < hotkeyAccessors.Length; i++)
|
||||
{
|
||||
HotkeyAccessor hotkeyAccessor = hotkeyAccessors[i];
|
||||
Shortcuts.Add((hotkeyAccessor.Value, () => _ipc.Send($"CustomPaste {i}")));
|
||||
}
|
||||
}
|
||||
|
||||
private void TryToPasteAsPlainText()
|
||||
{
|
||||
if (Clipboard.ContainsText())
|
||||
{
|
||||
string text = Clipboard.GetText();
|
||||
SendKeys.SendWait(text);
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_ipc?.Dispose();
|
||||
}
|
||||
|
||||
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get; } = [];
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using PowerToys.GPOWrapper;
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using PowerToys.GPOWrapper;
|
||||
|
||||
namespace ManagedCommon
|
||||
namespace RunnerV2.ModuleInterfaces
|
||||
{
|
||||
public interface IPowerToysModule
|
||||
{
|
||||
@@ -23,6 +25,8 @@ namespace ManagedCommon
|
||||
|
||||
public Dictionary<HotkeyEx, Action> Hotkeys { get => []; }
|
||||
|
||||
public List<(HotkeySettings Hotkey, Action Action)> Shortcuts { get => []; }
|
||||
|
||||
public Dictionary<string, Action> CustomActions { get => []; }
|
||||
|
||||
public void OnSettingsChanged(string settingsKind, JsonElement jsonProperties)
|
||||
@@ -3,13 +3,8 @@
|
||||
// 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.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using PowerToys.GPOWrapper;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
|
||||
namespace RunnerV2
|
||||
{
|
||||
@@ -186,5 +187,48 @@ namespace RunnerV2
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
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(
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string StringSecurityDescriptor,
|
||||
uint StringSDRevision,
|
||||
out IntPtr SecurityDescriptor,
|
||||
out uint SecurityDescriptorSize);
|
||||
|
||||
[DllImport("Advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool MakeAbsoluteSD(
|
||||
IntPtr pSelfRelativeSD,
|
||||
IntPtr pAbsoluteSD,
|
||||
ref uint lpdwAbsoluteSDSize,
|
||||
IntPtr pDacl,
|
||||
ref uint lpdwDaclSize,
|
||||
IntPtr pSacl,
|
||||
ref uint lpdwSaclSize,
|
||||
IntPtr pOwner,
|
||||
ref uint lpdwOwnerSize,
|
||||
IntPtr pPrimaryGroup,
|
||||
ref uint lpdwPrimaryGroupSize);
|
||||
|
||||
[DllImport("ole32.dll", SetLastError = true)]
|
||||
internal static extern int CoInitializeSecurity(
|
||||
IntPtr pSecDesc,
|
||||
int cAuthSvc,
|
||||
IntPtr asAuthSvc,
|
||||
IntPtr pReserved1,
|
||||
uint dwAuthnLevel,
|
||||
uint dwImpLevel,
|
||||
IntPtr pAuthList,
|
||||
uint dwCapabilities,
|
||||
IntPtr pReserved3);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint SendInput(uint nInputs, NativeKeyboardHelper.INPUT[] pInputs, int cbSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,20 @@ internal sealed class Program
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
string securityDescriptor =
|
||||
"O:BA" // Owner: Builtin (local) administrator
|
||||
+ "G:BA" // Group: Builtin (local) administrator
|
||||
+ "D:"
|
||||
+ "(A;;0x7;;;PS)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self
|
||||
+ "(A;;0x7;;;IU)" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users
|
||||
+ "(A;;0x3;;;SY)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system
|
||||
+ "(A;;0x7;;;BA)" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator
|
||||
+ "(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability
|
||||
+ "S:"
|
||||
+ "(ML;;NX;;;LW)"; // Integrity label on No execute up for Low mandatory level
|
||||
|
||||
COMUtils.InitializeCOMSecurity(securityDescriptor);
|
||||
|
||||
switch (ShouldRunInSpecialMode(args))
|
||||
{
|
||||
case SpecialMode.None:
|
||||
|
||||
@@ -15,8 +15,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using ManagedCommon;
|
||||
using RunnerV2.Helpers;
|
||||
using RunnerV2.ModuleInterfaces;
|
||||
using Update;
|
||||
using static RunnerV2.NativeMethods;
|
||||
|
||||
@@ -28,11 +28,6 @@ namespace RunnerV2
|
||||
|
||||
private const string TrayWindowClassName = "pt_tray_icon_window_class";
|
||||
|
||||
static Runner()
|
||||
{
|
||||
InitializeTrayWindow();
|
||||
}
|
||||
|
||||
public static List<IPowerToysModule> LoadedModules { get; } = [];
|
||||
|
||||
public static FrozenSet<IPowerToysModule> ModulesToLoad { get; } =
|
||||
@@ -40,10 +35,12 @@ namespace RunnerV2
|
||||
new ModuleInterfaces.AlwaysOnTopModuleInterface(),
|
||||
new ModuleInterfaces.HostsModuleInterface(),
|
||||
new ModuleInterfaces.PowerAccentModuleInterface(),
|
||||
new ModuleInterfaces.AdvancedPasteModuleInterface(),
|
||||
];
|
||||
|
||||
internal static bool Run(Action afterInitializationAction)
|
||||
{
|
||||
InitializeTrayWindow();
|
||||
TrayIconManager.StartTrayIcon();
|
||||
|
||||
Task.Run(UpdateUtilities.UninstallPreviousMsixVersions);
|
||||
@@ -53,6 +50,8 @@ namespace RunnerV2
|
||||
ToggleModuleStateBasedOnEnabledProperty(module);
|
||||
}
|
||||
|
||||
CentralizedKeyboardHookManager.Start();
|
||||
|
||||
afterInitializationAction();
|
||||
|
||||
MessageLoop();
|
||||
@@ -116,16 +115,23 @@ namespace RunnerV2
|
||||
{
|
||||
/* Todo: conflict manager */
|
||||
|
||||
if (!LoadedModules.Contains(module))
|
||||
{
|
||||
module.Enable();
|
||||
LoadedModules.Add(module);
|
||||
}
|
||||
|
||||
// ToArray is called to mitigate mutations while the foreach is executing
|
||||
foreach (var hotkey in module.Hotkeys.ToArray())
|
||||
{
|
||||
HotkeyManager.EnableHotkey(hotkey.Key, hotkey.Value);
|
||||
}
|
||||
|
||||
if (!LoadedModules.Contains(module))
|
||||
CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name);
|
||||
|
||||
foreach (var shortcut in module.Shortcuts.ToArray())
|
||||
{
|
||||
module.Enable();
|
||||
LoadedModules.Add(module);
|
||||
CentralizedKeyboardHookManager.AddKeyboardHook(module.Name, shortcut.Hotkey, shortcut.Action);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -149,6 +155,8 @@ namespace RunnerV2
|
||||
HotkeyManager.DisableHotkey(hotkey.Key);
|
||||
}
|
||||
|
||||
CentralizedKeyboardHookManager.RemoveAllHooksFromModule(module.Name);
|
||||
|
||||
LoadedModules.Remove(module);
|
||||
}
|
||||
catch (IOException)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
<ProjectReference Include="..\..\settings-ui\Settings.UI\PowerToys.Settings.csproj" />
|
||||
<ProjectReference Include="..\..\Update\Update.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -25,13 +25,6 @@
|
||||
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
<PropertyGroup>
|
||||
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="AdvancedPasteXAML\Controls\ClipboardHistoryItemPreviewControl.xaml" />
|
||||
<None Remove="AdvancedPasteXAML\Controls\PromptBox.xaml" />
|
||||
@@ -108,9 +101,9 @@
|
||||
<ItemGroup>
|
||||
<!-- HACK: Common.UI is referenced, even if it is not used, to force dll versions to be the same as in other projects that use it. It's still unclear why this is the case, but this is need for flattening the install directory. -->
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapperProjection\GPOWrapperProjection.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\LanguageModelProvider\LanguageModelProvider.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
@@ -22,6 +23,7 @@ using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using PowerToys.Interop;
|
||||
using Windows.Graphics;
|
||||
using WinUIEx;
|
||||
|
||||
@@ -132,47 +134,44 @@ namespace AdvancedPaste
|
||||
|
||||
if (cmdArgs?.Length > 2)
|
||||
{
|
||||
ProcessNamedPipe(cmdArgs[2]);
|
||||
TwoWayPipeMessageIPCManaged ipc = new(cmdArgs[2], string.Empty, async (m) => await OnNamedPipeMessage(m));
|
||||
ipc.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessNamedPipe(string pipeName)
|
||||
{
|
||||
void OnMessage(string message) => _dispatcherQueue.TryEnqueue(async () => await OnNamedPipeMessage(message));
|
||||
|
||||
Task.Run(async () => await NamedPipeProcessor.ProcessNamedPipeAsync(pipeName, connectTimeout: TimeSpan.FromSeconds(10), OnMessage, CancellationToken.None));
|
||||
}
|
||||
|
||||
private async Task OnNamedPipeMessage(string message)
|
||||
{
|
||||
var messageParts = message.Split();
|
||||
var messageType = messageParts.First();
|
||||
_dispatcherQueue.TryEnqueue(async () =>
|
||||
{
|
||||
var messageParts = message.Split();
|
||||
var messageType = messageParts.First();
|
||||
|
||||
if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage())
|
||||
{
|
||||
await ShowWindow();
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage())
|
||||
{
|
||||
await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage())
|
||||
{
|
||||
await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage())
|
||||
{
|
||||
await OnAdvancedPasteAdditionalActionHotkey(messageParts);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage())
|
||||
{
|
||||
await OnAdvancedPasteCustomActionHotkey(messageParts);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage())
|
||||
{
|
||||
Dispose();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
if (messageType == PowerToys.Interop.Constants.AdvancedPasteShowUIMessage())
|
||||
{
|
||||
await ShowWindow();
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteMarkdownMessage())
|
||||
{
|
||||
await viewModel.ExecutePasteFormatAsync(PasteFormats.Markdown, PasteActionSource.GlobalKeyboardShortcut);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteJsonMessage())
|
||||
{
|
||||
await viewModel.ExecutePasteFormatAsync(PasteFormats.Json, PasteActionSource.GlobalKeyboardShortcut);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteAdditionalActionMessage())
|
||||
{
|
||||
await OnAdvancedPasteAdditionalActionHotkey(messageParts);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteCustomActionMessage())
|
||||
{
|
||||
await OnAdvancedPasteCustomActionHotkey(messageParts);
|
||||
}
|
||||
else if (messageType == PowerToys.Interop.Constants.AdvancedPasteTerminateAppMessage())
|
||||
{
|
||||
Dispose();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||
|
||||
@@ -7,16 +7,16 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
{
|
||||
internal static class NativeKeyboardHelper
|
||||
public static class NativeKeyboardHelper
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||
internal struct INPUT
|
||||
public struct INPUT
|
||||
{
|
||||
internal INPUTTYPE type;
|
||||
internal InputUnion data;
|
||||
public INPUTTYPE type;
|
||||
public InputUnion data;
|
||||
|
||||
internal static int Size
|
||||
public static int Size
|
||||
{
|
||||
get { return Marshal.SizeOf<INPUT>(); }
|
||||
}
|
||||
@@ -24,49 +24,49 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||
internal struct InputUnion
|
||||
public struct InputUnion
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal MOUSEINPUT mi;
|
||||
public MOUSEINPUT mi;
|
||||
[FieldOffset(0)]
|
||||
internal KEYBDINPUT ki;
|
||||
public KEYBDINPUT ki;
|
||||
[FieldOffset(0)]
|
||||
internal HARDWAREINPUT hi;
|
||||
public HARDWAREINPUT hi;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||
internal struct MOUSEINPUT
|
||||
public struct MOUSEINPUT
|
||||
{
|
||||
internal int dx;
|
||||
internal int dy;
|
||||
internal int mouseData;
|
||||
internal uint dwFlags;
|
||||
internal uint time;
|
||||
internal UIntPtr dwExtraInfo;
|
||||
public int dx;
|
||||
public int dy;
|
||||
public int mouseData;
|
||||
public uint dwFlags;
|
||||
public uint time;
|
||||
public UIntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||
internal struct KEYBDINPUT
|
||||
public struct KEYBDINPUT
|
||||
{
|
||||
internal short wVk;
|
||||
internal short wScan;
|
||||
internal uint dwFlags;
|
||||
internal int time;
|
||||
internal UIntPtr dwExtraInfo;
|
||||
public short wVk;
|
||||
public short wScan;
|
||||
public uint dwFlags;
|
||||
public int time;
|
||||
public UIntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Matching Native Structure")]
|
||||
internal struct HARDWAREINPUT
|
||||
public struct HARDWAREINPUT
|
||||
{
|
||||
internal int uMsg;
|
||||
internal short wParamL;
|
||||
internal short wParamH;
|
||||
public int uMsg;
|
||||
public short wParamL;
|
||||
public short wParamH;
|
||||
}
|
||||
|
||||
internal enum INPUTTYPE : uint
|
||||
public enum INPUTTYPE : uint
|
||||
{
|
||||
INPUT_MOUSE = 0,
|
||||
INPUT_KEYBOARD = 1,
|
||||
@@ -74,7 +74,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum KeyEventF
|
||||
public enum KeyEventF
|
||||
{
|
||||
KeyDown = 0x0000,
|
||||
ExtendedKey = 0x0001,
|
||||
|
||||
Reference in New Issue
Block a user