2010-04-26 84 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