C# WPF Windows程序TCP接收数据后向第三方应用发送文本方案咨询
实现方案
核心逻辑
你要实现的效果和硬件扫码枪完全一致:用户将光标提前定位到任意应用的输入框中,接收到TCP数据后直接模拟输入到当前激活的输入位置即可,无需绑定指定应用进程。
方案1:简化原有代码(快速实现)
直接移除你原有Send方法中绑定记事本进程的逻辑,SendKeys默认会将内容发送到当前系统前台激活的输入焦点:
public void Send(String data) { // 移除查找指定进程、切换前台的逻辑,直接发送 SendKeys.SendWait(data); }
注意事项
- 你的TCP服务端不能以Windows服务的形式运行(Windows服务运行在隔离的Session 0,无用户交互权限),改为普通桌面应用,设置开机自启、隐藏窗口即可正常使用
- 遇到特殊字符(回车、制表符、功能键等)需要按照
SendKeys的规则转义,例如回车写为{ENTER}、Tab写为{TAB}
方案2:使用SendInput API(更稳定兼容)
SendKeys对部分应用、特殊字符的兼容性较差,推荐使用Windows原生SendInputAPI模拟键盘输入,稳定性更高:
using System.Runtime.InteropServices; [DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); [StructLayout(LayoutKind.Sequential)] private struct INPUT { public uint type; public InputUnion u; } [StructLayout(LayoutKind.Explicit)] private struct InputUnion { [FieldOffset(0)] public MOUSEINPUT mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] private struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] private struct HARDWAREINPUT { public uint uMsg; public ushort wParamL; public ushort wParamH; } private const uint INPUT_KEYBOARD = 1; private const uint KEYEVENTF_UNICODE = 0x0004; private const uint KEYEVENTF_KEYUP = 0x0002; public void Send(string data) { foreach (char c in data) { INPUT[] inputs = new INPUT[2]; // 按键按下 inputs[0].type = INPUT_KEYBOARD; inputs[0].u.ki.wScan = c; inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE; // 按键抬起 inputs[1].type = INPUT_KEYBOARD; inputs[1].u.ki.wScan = c; inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))); } }
这个方案支持中文、特殊字符的输入,对绝大多数应用的兼容性都远高于SendKeys。
可选扩展:无焦点输入
如果需要实现即使目标窗口未处于前台也能输入,可以通过获取当前焦点控件的句柄,发送WM_SETTEXT消息实现:
[DllImport("user32.dll")] private static extern IntPtr GetFocus(); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam); private const uint WM_SETTEXT = 0x000C; public void SendWithoutFocus(string data) { IntPtr focusHwnd = GetFocus(); if (focusHwnd != IntPtr.Zero) { SendMessage(focusHwnd, WM_SETTEXT, IntPtr.Zero, data); } }
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

