2010-04-26 61 views
0

對於一個項目,我必須在C#中啓動一個應用程序,撕掉與該進程相關的AutomationElement樹,然後關閉該應用程序並輸出該樹。我通過使用Process.Start打開應用程序來做到這一點。然後,我找到與生成的過程相關的AutomationElement,並使用TreeWalker和AutomationElement的FindFirst和FindAll方法的組合來遍歷樹。Hudson似乎不運行Process.Start正確

這在我的電腦上運行良好,並且在本地使用NUnit正確運行。它也運行在我的組計算機上的其他人。問題在於,它永遠不會運行在運行Hudson的中央測試服務器上。經過幾個小時的調試後,我對Hudson進行了測試,啓動該應用程序,然後打印AutomationTree的第一層。在我的電腦上,這會打印我桌面上的所有窗口。在Hudson上,這隻能打印桌面。

考慮到可能有多個桌面,我嘗試在RootElement上使用TreeWalker的GetNextSibling函數。它仍然只報告一個桌面。

下面是我用來啓動進程的代碼。

public bool connect(string[] args) 
{ 
    if (this.process != null) { 
     Console.WriteLine("ERROR: Process already connected"); 
     return false; 
    } 

    if (!File.Exists(sApplicationPath)) { 
     Console.WriteLine(sApplicationPath + " does not exist"); 
     return false; 
    } 

    // Turn the command arguments into a single string 
    string arguments = ""; 
    foreach (string arg in args) { 
     arguments += arg + " "; 
    } 

    try { 
     // Start the application 
     ProcessStartInfo processStartInfo = 
      new ProcessStartInfo(sApplicationPath); 
     processStartInfo.Arguments = arguments; 
     this.process = Process.Start(processStartInfo); 

     // Must be a positive integer (non-zero) 
     if (!(iInitialDelay > 0) ) { 
      Console.WriteLine("Invalid initial delay. " + 
           "Defaulting to 5 seconds."); 
      this.iInitialDelay = 5000; 
     } 

     Thread.Sleep(this.iInitialDelay); 
    } catch (Exception ex) { 
     Console.WriteLine("WGApplication.connect: " + ex.Message); 
     return false; 
    } 

    // Check if the process still exists 
    try { 
     /** This part does not return an error, so I think that means the process exists and is started */ 
     Process check = Process.GetProcessById(process.Id); 
    } catch (ArgumentException ex) { 
     Console.WriteLine("The process expired before connection was complete"); 
     Console.WriteLine("Make sure the process is not open anywhere else"); 
     Console.WriteLine("and that it is able to execute on the host machine."); 
     return false; 
    } 

    // Check if the base automation element exists to verify open 
    AutomationElement rootWindow = 
     AutomationElement.RootElement.FindChildProcessById(process.Id); 
    /** This part returns null, so it can't find the window associated with this process id */ 

    if (this.process == null) { 
     return false; 
    } else if (rootWindow == null) { 
     // A root window with this process id has not been found 
     Console.WriteLine("Cannot find the root window of the created " + 
          "process. Unknown error."); 
     return false; 
    } else { 
     // Everything is good to go 
     return true; 
    } 
} 

sApplicationPath設置爲可執行文件的絕對路徑。 iInitialDelay是確保應用程序有時間啓動的延遲。我在Windows Vista SP2上的'C:\ Windows \ System32 \ notepad.exe'上運行它,並使用v3.5 C#編譯器編譯它。

FindChildProcessById定義如下:

public static AutomationElement FindChildProcessById(
    this AutomationElement element, int processId) 
{ 
    var result = element.FindChildByCondition(
     new PropertyCondition(AutomationElement.ProcessIdProperty, 
           processId)); 

    return result; 
} 

請記住,這編譯和工作在我的電腦上。我在哈德森的測試計劃表示,RootElement根本沒有孩子。

因此,我啓動應用程序,確認它存在,然後我找不到與該過程相關聯的任何窗口。除了桌面以外,我找不到任何與窗口相關的窗口。

這是Hudson問題嗎? Hudson是否以某種特定的方式工作,這些代碼不適用於它?這是我的代碼問題嗎? Hudson服務器在Windows Server 2003計算機上運行。任何幫助,將不勝感激。我知道這是一個非常具體的問題,這是我無法在網上找到任何解決方案的原因。

回答

1

哈德森是否作爲服務運行?如果是這樣,它可能沒有必要的權利來顯示窗口。

+0

我在半小時前與正在運行服務器的教授交談。我相信它是作爲服務運行的,他說它禁用了桌面訪問。我今晚會更新你的權限。 – 2010-04-26 20:07:53

+0

那一定是它。他檢查了一下,它正在工作。謝謝您的幫助。 – 2010-04-27 18:35:55