2011-03-21 36 views
1

我正在嘗試自動化不提供此類自動化功能的產品。如何從單獨的運行過程捕獲表單事件

我已經粗略看了一下在單獨的AppDomain中加載應用程序,並且還通過反射執行了Program.Main()以使應用程序運行。我也嘗試從單獨創建的Process對象獲取窗口句柄(我學到的不會工作)。

如果我將其程序集引用添加到我的項目中,那麼我可以引用「TheirProduct.FormMain」實例,如果有可能,是從該窗體捕獲事件的最佳方法?

我需要做的是能夠捕捉一對夫婦的事件,並對窗體執行一些Button.PerformClick()。

+0

這是不可能的,事件處理程序必須在進程中註冊。看看Managed Spy ++。但與程序供應商或作者合作是取得成功的最佳途徑。 – 2011-03-21 17:58:18

回答

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自動化庫旨在與名爲控件的模擬客戶端一起工作,但它也適用於幾乎任何程序。如果你沒有很好地模擬你的程序,那麼你將不得不像上面那樣進行破解。

有大量關於這一主題閱讀:

你可能會發現它很有用間諜++檢查你的程序了。

+1

這絕對會讓我受益匪淺。超級好消息,是供應商讓我在他們的來源。 (這是意想不到的) – hometoast 2011-03-24 11:16:41

相關問題