SendKeys Is Not Working In Windows 10

The Steve Gaines Laptop Band 21 Reputation points
2022-07-17T00:44:49.377+00:00

I am creating a program in Visual Studio with C#. I want to send some keystrokes to another application running on my same laptop. I will post the code I am using below. Nothing happens when I click the button. I have proved with break points that it is finding the handle to the window, but even when I run it with no break point the key strokes never appear. I did get it to sort of work when I put in a timer event. If I started the app and then brought Notepad to the foreground then the keystrokes would appear. I may be able to get that to work, If I must. Is there a better way to code this that will work, or is SetForegroundWindpw blocked in Windows 10?

public partial class Form1 : Form  
{  
    [DllImport("User32.dll")]  
    static extern bool SetForegroundWindow(IntPtr point);  

    private void button1_Click(object sender, EventArgs e)  
    {  
        var p = Process.GetProcessesByName("notepad")[0];  
        var pointer = p.Handle;  
        SetForegroundWindow(pointer);  
        SendKeys.Send("This is a test.");  
    }  
}  
Developer technologies | Windows Forms
{count} votes

Accepted answer
  1. Castorix31 90,956 Reputation points
    2022-07-17T07:09:40.343+00:00

    The parameter for SetForegroundWindow is a Window handle, not a Process handle.
    And SwitchToThisWindow works better (if it is minimized) :

                var p = System.Diagnostics.Process.GetProcessesByName("notepad").FirstOrDefault();  
                var hWnd = p.MainWindowHandle;  
                //SetForegroundWindow(hWnd);  
                SwitchToThisWindow(hWnd, true);  
                SendKeys.Send("This is a test.");  
    

    with

        [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]  
        public static extern bool SwitchToThisWindow(IntPtr hWnd, bool fAltTab);  
    
    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Reza Aghaei 4,991 Reputation points MVP
    2022-07-18T01:07:18.23+00:00

    Here are two more solutions to send keys or set text of a specific control in another process which you may find useful in some scenarios:

    • Using UI Automation
    • Sending WM_SETTEXT message

    Using UI Automation

    Using UI Automation, you can get the specific automation element of the main window of the process and query its child to find your desired element. Then send data using either of ValuePattern, or SendKeysm or SendMessage.

    To learn more about UI Automation, take a look at:

    Here is an example to send text to notepad:

    var notepad = System.Diagnostics.Process.GetProcessesByName("notepad").FirstOrDefault();
    if (notepad != null)
    {
        var root = AutomationElement.FromHandle(notepad.MainWindowHandle);
        var element = root.FindAll(TreeScope.Subtree, Condition.TrueCondition)
            .Cast<AutomationElement>()
            .Where(x => x.Current.ClassName == "Edit" &&
                x.Current.AutomationId == "15").FirstOrDefault();
        if (element != null)
        {
            if (element.TryGetCurrentPattern(ValuePattern.Pattern, out object pattern))
            {
                ((ValuePattern)pattern).SetValue("This is a test.");
            }
            else
            {
                element.SetFocus();
                SendKeys.SendWait("^{HOME}");   // Move to start of control
                SendKeys.SendWait("^+{END}");   // Select everything
                SendKeys.SendWait("{DEL}");     // Delete selection
                SendKeys.SendWait("This is a test.");
               // OR 
               // SendMessage(element.Current.NativeWindowHandle, WM_SETTEXT, 0, "This is a test.");
            }
        }
    }
    

    Sending WM_SETTEXT message

    Using FindWindowEx, you can find the specific control of the main window of the other process, and then set the text using WM_SETTEXT, for exapmle:

    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
        string lpszClass, string lpszWindow);
    [DllImport("User32.dll")]
    static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, string lParam);
    const int WM_SETTEXT = 0x000C;
    
    private void button1_Click(object sender, EventArgs e)
    {
        //Find notepad by its name, or use the instance which you opened yourself
        var notepad = Process.GetProcessesByName("notepad").FirstOrDefault();
        if(notepad!=null)
        {
            var edit = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null);
            SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "This is a test.");
        }
    }
    
    0 comments No comments

  2. Shadow_ 0 Reputation points
    2025-07-15T09:24:27.4866667+00:00

    Find your .csproj file in your project folder right click and click edit with notepad

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
    
      <PropertyGroup>
        ...
        <TargetFramework>net8.0-windows</TargetFramework>
        ...
        ...
        ....
        <UseWindowsForms>true</UseWindowsForms>
      </PropertyGroup>
    
      ....
    </Project>
    
    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
    
    <TargetFramework>net8.0-windows</TargetFramework>
    
    <UseWindowsForms>true</UseWindowsForms>
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.