Paste submitted text via clipboard

This commit is contained in:
Misaka
2026-05-15 22:50:09 +08:00
parent 0c2cbbfccd
commit 046a27ecf9

View File

@@ -13,6 +13,7 @@ public sealed class KeyboardInjectionService : IKeyboardInjectionService
private const ushort VirtualKeyBack = 0x08; private const ushort VirtualKeyBack = 0x08;
private const ushort VirtualKeyControl = 0x11; private const ushort VirtualKeyControl = 0x11;
private const ushort VirtualKeyReturn = 0x0D; private const ushort VirtualKeyReturn = 0x0D;
private const ushort VirtualKeyV = 0x56;
private static readonly IntPtr EnglishKeyboardLayout = LoadKeyboardLayout("00000409", KlfActivate); private static readonly IntPtr EnglishKeyboardLayout = LoadKeyboardLayout("00000409", KlfActivate);
public void InsertText(string text) public void InsertText(string text)
@@ -22,7 +23,13 @@ public sealed class KeyboardInjectionService : IKeyboardInjectionService
return; return;
} }
AppLogger.Info($"Injecting text length: {text.Length}"); AppLogger.Info($"Pasting text length: {text.Length}");
PasteTextViaClipboard(text);
}
private static void TypeTextWithSendInput(string text)
{
AppLogger.Info($"Falling back to SendInput text length: {text.Length}");
using var keyboardLayoutScope = KeyboardLayoutScope.SwitchForegroundWindowToEnglish(); using var keyboardLayoutScope = KeyboardLayoutScope.SwitchForegroundWindowToEnglish();
foreach (var character in text) foreach (var character in text)
{ {
@@ -32,6 +39,68 @@ public sealed class KeyboardInjectionService : IKeyboardInjectionService
} }
} }
private static void PasteTextViaClipboard(string text)
{
Exception? failure = null;
var thread = new Thread(() =>
{
try
{
PasteTextOnStaThread(text);
}
catch (Exception ex)
{
failure = ex;
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
if (failure is not null)
{
AppLogger.Error("Clipboard paste failed.", failure);
TypeTextWithSendInput(text);
}
}
private static void PasteTextOnStaThread(string text)
{
var hadText = Clipboard.ContainsText(TextDataFormat.UnicodeText);
var previousText = hadText ? Clipboard.GetText(TextDataFormat.UnicodeText) : null;
try
{
Clipboard.SetText(text, TextDataFormat.UnicodeText);
Thread.Sleep(30);
SendModifiedKey(VirtualKeyControl, VirtualKeyV);
Thread.Sleep(150);
}
finally
{
RestoreClipboardText(hadText, previousText);
}
}
private static void RestoreClipboardText(bool hadText, string? previousText)
{
try
{
if (hadText && previousText is not null)
{
Clipboard.SetText(previousText, TextDataFormat.UnicodeText);
return;
}
Clipboard.Clear();
}
catch (Exception ex)
{
AppLogger.Error("Failed to restore clipboard text.", ex);
}
}
public void ReplaceFocusedText(string text) public void ReplaceFocusedText(string text)
{ {
AppLogger.Info($"Replacing focused text length: {text.Length}"); AppLogger.Info($"Replacing focused text length: {text.Length}");