The simplest way is to use AutoIt, which is a great wrapper for Windows API. It also has a built-in Window Info Tool:
With a few lines you can write an automation script. For example, we call a notepad window, wait for its show-up, send text to it and then close it without saving:
Run("notepad.exe")WinWaitActive("Untitled - Notepad")Send("This is some text.")WinClose("Untitled - Notepad")WinWaitActive("Notepad", "Do you want to save");Send("!n") //Alt-n to quit notepad without saving
IntPtr hWnd = IntPtr.Zero;
foreach (Process pList in Process.GetProcesses())
{
if (pList.MainWindowTitle.Contains(wName))
hWnd = pList.MainWindowHandle;
}
return hWnd; //Note: may be zero if can't find a matched title
Or we can call Windows API directly in C#. For wait for Window Active, we can use a timer to find window periodically:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
private void timer1_tick(object sender, EventArgs e)
{
Process [] notepads = Process.GetProcessesByName("notepad");
if(notepads.Length==0) return; else timer1.enabled=false;
if (notepads[0] != null)
{
IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
SendMessage(child, 0x000C, 0, textBox1.Text);
}
}
For program like Notepad, it's better to find process first, because the title of window is changed by it's content.There is a great Windows message APIs wrapper for using WM_DATACOPY called MessageHelper :
https://gist.github.com/BoyCook/5075907
More advanced UI automation tricks can be found in:
UI Automation Clients for Managed Code
One important application of Windows Automation is to send inputs (keys or mouse clicks) to background Windows. However, I didn't found an effective way to do this task. SendMessage or PeekMessage not always work. The current method I am using is to set my application on top, call "SetForegroundWindow" and "SendKeys". For mouse clicks, I'm still looking for effective method.
// import the function in your class
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);
// Find the target process and send keys
Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
if (p != null)
{
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.Send("{F1}");
SendKeys.SendWait("{Enter}");
}
沒有留言:
張貼留言