Проблемы с кодировкой c# sendkeys

196
15 марта 2018, 07:34

Если sendkeys'ом отправлять такую строку:

SendKeys.send("Привет");

То всё работает прекрасно.

Но если же сделать вот так:

SendKeys.send("Привет, world");

То начинается ужас из "????" ИЛИ "цщкдв".

Что с этим можно сделать? Как отправить "Привет, world" нормально?

Answer 1

Это никак не связано с кодировкой. Дело в том, что в Windows раскладка клавиатуры задается на уровне потоков. По некоторым причинам, SendKeys работает некорректно, если для потока, которому принадлежит целевое окно, установлена другая раскладка, чем для текущего потока - либо для русских, либо для английских букв будет генерироваться сообщение с несоответствующим скан-кодом.

Эту проблему можно решить, изменив раскладку текущего потока так, чтобы они совпадали:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
namespace WindowsFormsTest1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);        
        [DllImport("user32.dll")]
        static extern IntPtr GetKeyboardLayout(uint thid);        
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern IntPtr ActivateKeyboardLayout(IntPtr hkl, uint Flags);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process pr = Process.GetProcessesByName("notepad")[0];
            IntPtr hwnd = pr.MainWindowHandle;            
            //получение идентификатора потока целевого окна
            uint dummy = 0;
            uint thid = GetWindowThreadProcessId(hwnd, out dummy);
            //смена раскладки клавиатуры на раскладку целевого окна
            IntPtr id = GetKeyboardLayout(thid); 
            ActivateKeyboardLayout(id, 0);           
            SetForegroundWindow(hwnd);//передаем фокус окну
            SendKeys.Send("Hello, мир");//теперь должно сработать
        }
    }    
}
READ ALSO
Не так работает спраит (Unity) [требует правки]

Не так работает спраит (Unity) [требует правки]

День ДобрыйНачал не давно изучать Unity и столкнулся с проблемой

209
C# Как сделать рамку для обрезания?

C# Как сделать рамку для обрезания?

Здравствуйте, как сделать рамку для обрезания фотографии? Фотография расположена в pictureBox1, рамка нужна чтобы она двигалась и размеры можно...

193
Проверка пересечения фигур

Проверка пересечения фигур

Есть класс фигуры у которой в поле хранится тип(1 - прямоугольник, 2 - отрезок, 3 - круг), нужно написать метод проверки имеются ли общие точки...

214
Таймаут остановки Win-service

Таймаут остановки Win-service

Для теста мне нужен сервис который будет останавливаться 10-15 мин

202