我正在尝试自动化不提供此类自动化功能的产品。
我粗略地看一下在单独的AppDomain中加载应用程序,并通过反射执行Program.Main()以使应用程序运行。我也尝试从单独创建的Process对象中获取windowhandle(我学到的不会起作用)。
如果我对他们的程序集的引用添加到我的项目中,那么我可以引用“TheyProduct.FormMain”的实例,如果可能的话,那么从该表单中捕获事件的最佳方法是什么?
我需要做的是能够捕获一些事件,并对表单执行一些Button.PerformClick()。
答案 0 :(得分:4)
查看Microsoft UI自动化库,它附带.Net 3.5和4.0。这是4.0的代码示例,只需添加对UIAutomationClient和UIAutomationTypes的引用。程序启动计算器并按下一些按钮。
Option Explicit On
Option Strict On
Imports System.Windows.Automation
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
''//Start the calculator
Using P = Process.Start("calc.exe")
''//Hack, pause for a bit while calculator starts
System.Threading.Thread.Sleep(2000)
''//Try and grab the calculator window
Dim CalcWindow = AutomationElement.FromHandle(P.MainWindowHandle)
''//Make sure we've got something
If CalcWindow Is Nothing Then Throw New ApplicationException("Could find calculator window")
''//Grab all of the calculator buttons
Dim Buttons = CalcWindow.FindAll(TreeScope.Descendants, New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button))
If (Buttons Is Nothing) OrElse (Buttons.Count = 0) Then Throw New ApplicationException("Could not find any buttons on the calculator")
''//Grab individual buttons by label
Dim B5 = GetObjectByLabel(Buttons, "5")
Dim BAdd = GetObjectByLabel(Buttons, "Add")
Dim B7 = GetObjectByLabel(Buttons, "7")
Dim BEquals = GetObjectByLabel(Buttons, "Equals")
''//Press the buttons
DirectCast(B5.GetCurrentPattern(InvokePattern.Pattern), InvokePattern).Invoke()
DirectCast(BAdd.GetCurrentPattern(InvokePattern.Pattern), InvokePattern).Invoke()
DirectCast(B7.GetCurrentPattern(InvokePattern.Pattern), InvokePattern).Invoke()
DirectCast(BEquals.GetCurrentPattern(InvokePattern.Pattern), InvokePattern).Invoke()
End Using
End Sub
Private Shared Function GetObjectByLabel(ByVal objects As AutomationElementCollection, ByVal label As String) As AutomationElement
''//Sanity check
If objects Is Nothing Then Throw New ArgumentNullException("objects")
If label Is Nothing Then Throw New ArgumentNullException("label")
''//Loop through each looking by name
For Each B As AutomationElement In objects
If B.Current.Name = label Then Return B
Next
Return Nothing
End Function
End Class
UI自动化库旨在与具有命名控件的模拟客户端一起使用,但它也适用于几乎任何程序。如果你没有很好地模拟你的程序那么你将不得不像我上面那样破解。
有很多关于这个主题的内容:
您可能会发现使用Spy ++检查程序也很有用。