0

プロジェクトでは、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 コンピューターで実行されています。どんな助けでも大歓迎です。これが非常に具体的な問題であることはわかっています。これが、オンラインで解決策が見つからない理由です。

4

1 に答える 1

1

Hudson はサービスとして実行されていますか? その場合、ウィンドウを表示するために必要な権限がない可能性があります。

于 2010-04-26T19:02:22.670 に答える