38

I want to send a specific key (e.g. k) to another program named notepad, and below is the code that I used:

private void SendKey()
{
    [DllImport ("User32.dll")]
    static extern int SetForegroundWindow(IntPtr point);

    var p = Process.GetProcessesByName("notepad")[0];
    var pointer = p.Handle;

    SetForegroundWindow(pointer);
    SendKeys.Send("k");
}
            

But the code doesn't work, what's wrong with the code?

Is it possible that I send the "K" to the notepad without notepad to be the active window? (e.g. active window = "Google chrome", notepad is in the background, which means sending a key to a background application)?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
User2012384
  • 4,769
  • 16
  • 70
  • 106
  • do you get any error? – Zaki Mar 08 '13 at 10:46
  • No I don't, instead, it just send the "K" to the top window – User2012384 Mar 08 '13 at 10:47
  • 1
    see if this helps : http://stackoverflow.com/questions/825651/how-can-i-send-the-f4-key-to-a-process-in-c – Zaki Mar 08 '13 at 10:47
  • 1
    It works, but what the program does is to send the key to an already opened program, instead of starting the program programmably – User2012384 Mar 08 '13 at 10:51
  • Does notepad becomes foreground window ? I guess that this is a problem, see docs for SetForegroundWindow, under remarks : http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539%28v=vs.85%29.aspx – Antonio Bakula Mar 08 '13 at 11:03
  • is notepad allready started when you call this method ? – Antonio Bakula Mar 08 '13 at 11:13
  • yes, I'm sure notepad had started and if i'm right, notepad was the foreground window (return result 0) – User2012384 Mar 08 '13 at 11:16
  • worth noting the dllimport line is `System.Runtime.InteropServices.DllImport` so without that absolute path you'd need a using line for it, and I think those two lines the dllimport line and the extern line, go within the class outside the methods. – barlop Nov 10 '17 at 23:58
  • 1
    if you add the code posted by jandex https://stackoverflow.com/questions/2423234/make-a-form-not-focusable-in-c-sharp/2428108#2428108 to your form then you can sendkeys to whatever application is active.. your program/form won't take focus and nothing on your form, will take the focus.. – barlop Nov 11 '17 at 01:41

3 Answers3

70

If notepad is already started, you should write:

// import the function in your class
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);

//...

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
if (p != null)
{
    IntPtr h = p.MainWindowHandle;
    SetForegroundWindow(h);
    SendKeys.SendWait("k");
}

GetProcessesByName returns an array of processes, so you should get the first one (or find the one you want).

If you want to start notepad and send the key, you should write:

Process p = Process.Start("notepad.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");

The only situation in which the code may not work is when notepad is started as Administrator and your application is not.

Mohammad Dehghan
  • 17,853
  • 3
  • 55
  • 72
  • But I don't want to start the program programably, what I want to do is to send the key to an running program, is there any way to do this? – User2012384 Mar 08 '13 at 11:15
  • @HugoWong The only situation in which the code may not work is when `notepad` is started as Administrator and your application is not. – Mohammad Dehghan Mar 08 '13 at 12:17
  • 1
    I just read an article about it not always working on Windows 7, which is what I'm running, the funny thing is, it works for some apps, but not the one I'm trying to dump text into. – Glenn Cuevas Aug 13 '15 at 06:05
  • @GlennCuevas Describe your exact situation in a new question, and I'll happily answer that. – Mohammad Dehghan Aug 13 '15 at 08:38
  • https://www.pinvoke.net/default.aspx/user32/setforegroundwindow.html defines extern method SetForegroundWindow(IntPtr point) as: [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetForegroundWindow(IntPtr hWnd); – lison Apr 25 '19 at 13:12
  • @lison Yes but they have exactly the same effect. The pinvoke.net signature is more correct, as it uses the designated constructs (`UnmanagedType.bool` is the equivalent of Win32's `BOOL` macro, which is defined as `int`). Mine is hand-converted signature, when I didn't read the entire documentation for P/Invoke :) – Mohammad Dehghan Apr 25 '19 at 20:46
  • @Triynko I guess maybe due to security reasons, if some ill-intention people write some nasty code and start a program and write some input without the permission of the user, it could be dangerous. Just like Android, they don't have the API to turn on / off the flight mode, they can only open the settings and the user have to click it by himself – User2012384 Jun 19 '21 at 14:40
  • That might be true in this case, but so often I have used an API that is so needlessly complex and "security" gets the blame – arynaq Aug 09 '21 at 10:08
0
    public string h1;
    public string h2;
    public string m1;
    public string m2;
    public string s1;
    public string s2;

   public partial class Form1 

    hours hour = new hours();
Sendkeys.SendWait(Convert.ToString(hour.h1+hour.h2+hour.m1+hour.m2+hour.s1+hour.s2              +" "));   

it is a simple matter of sending a classed string to the sendkey process using the convert to string procedure

0

You can send anything by first copying into the clipboard and then paste the send keys ctrl+v:

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();

if (p != null)
{
    IntPtr h = p.MainWindowHandle;
    SetForegroundWindow(h);
    Clipboard.Clear();
    Clipboard.SetText(txtCode.Text); 
    string strClip = Clipboard.GetText();
    SendKeys.Send("^{v}");
}
Lemon
  • 140
  • 1
  • 3
  • 13