プロジェクトでは、C# でアプリケーションを起動し、プロセスに関連する AutomationElement ツリーを取り出し、アプリケーションを閉じてツリーを出力する必要があります。これを行うには、Process.Start を使用してアプリケーションを開きます。次に、生成されたプロセスに関連する AutomationElements を見つけ、TreeWalker と AutomationElement の FindFirst メソッドと FindAll メソッドを組み合わせてツリーをたどっています。
これは私のコンピューターで正常に動作し、ローカルで NUnit を使用して正しく動作します。また、私のグループのコンピューターの他の人でも実行されます。問題は、Hudson を実行している中央のテスト サーバーでは決して実行されないことです。数時間のデバッグの後、Hudson でアプリケーションを起動し、AutomationTree の最初のレベルを出力するテストを行いました。私のコンピューターでは、デスクトップにあるすべてのウィンドウが印刷されます。Hudson では、これはデスクトップのみを印刷します。
複数のデスクトップがあるのではないかと考えて、RootElement で TreeWalker の GetNextSibling 関数を使用してみました。まだ 1 つのデスクトップしか報告されていません。
プロセスを開始するために使用しているコードは次のとおりです。
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;
}
これは私のコンピューターでコンパイルして動作することを覚えておいてください。Hudson でのテスト プログラムでは、RootElement に子がまったくないことが示されました。
そのため、アプリケーションを起動し、存在することを確認しましたが、プロセスに関連付けられたウィンドウが見つかりません。デスクトップ以外に関連付けられたウィンドウが見つかりません。
これはハドソンの問題ですか?Hudson は、このコードが動作しない特定の方法で動作しますか? 私のコードに問題がありますか?Hudson サーバーは、Windows Server 2003 コンピューターで実行されています。どんな助けでも大歓迎です。これが非常に具体的な問題であることはわかっています。これが、オンラインで解決策が見つからない理由です。