views:

132

answers:

2

I am trying to make C# launch an application (in this case open office), and start sending that application keypresses such that it would appear as though someone is typing. So ideally, I would be able to send a running open office process the keypress for the letter "d", and open office would then type d on the paper. Can anyone give me direction as per how to go about this? I have tried to do the following:

p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.CreateNoWindow = false;
p.StartInfo.FileName = processNames.executableName;

p.Start();

p.StandardInput.Write("hello");

But that doesn't get me the desired effect - I don't see the text typed out in open office.

+2  A: 

You have to do this via Win32 sendmessages: The basic idea is like this:

Fist you need a pointer to the launched process window:

using System.Runtime.InteropServices;

[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

private void button1_Click(object sender, EventArgs e)
{
  // Find a window with the name "Test Application"
  IntPtr hwnd = FindWindow(null, "Test Application");
}

then use SendMessage or PostMessage (preferred in your case I guess):

http://msdn.microsoft.com/en-us/library/ms644944(v=VS.85).aspx

In this message specify the correct message type (e.g. WM_KEYDOWN) to send a keypress:

http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx

Have a look at PInvoke.net to get PInvoke sourcecode.

Alternatively you can use the SendKeys.Send (.Net) method after using FindWindow to bring that window to the foreground. However that is somewhat unreliable.

Foxfire
+1 This answer should get @Waffles thinking in the right direction...
Gordon
+1  A: 

I did this using SetForegroundWindow and SendKeys.

I used it for this.

[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);

public void SendText(IntPtr hwnd, string keys)
{
    if (hwnd != IntPtr.Zero)
    {
        if (SetForegroundWindow(hwnd))
        {
            System.Windows.Forms.SendKeys.SendWait(keys);
        }
    }
}

This can be used as simply as this.

Process p = Process.Start("notepad.exe");
SendText(p.MainWindowHandle, "Hello, world");
Cory