none
子ウィンドウのタイトルを取得するための知識をご教示いただきたい

    質問

  • お世話になります。

    PowerShellで、親ウィンドウが出しているダイアログボックスのタイトルや子コントロールを取得する方法はありますでしょうか。

    子ウィンドウタイトルやHandleが何かがつかめず、行き詰まっております。

    お手数をおかけしますがご教示いただければ幸いです。

    ■状況

    アプリケーションは以下のような構造を持っています。

    ***************************

    MyApp ("メインウィンドウ")
     └ MyApp2("ダイアログ表示")

    ***************************

    メインウィンドウから、ダイアログ表示をした状態で、

    Spy++を使いそれぞれのウィンドウハンドルを確認したところ以下の状態でした。

    MyApp   : 00B41C2C(HEX)
    MyApp2   : 00120C68(HEX)


    ■Script

    PowerShellで以下のスクリプトを流します。

    # 名前からProcessを取得
    $appName = "MyApp"
    $p = $null
    try {
        $p = get-process $appname
        if ( $null -eq $p ) {
            Write-Host ("PID is null.")
            exit
        } else {
            Write-Host ("id is " + $p.Id)
        }
    } catch {
        Write-Error("error "+$_.Exception)
        exit
    } finally {
        Write-Host ("")
    }
    
    Write-Host $p.MainWindowTitle #-> "メインウィンドウ"
    Write-Host $p.MainWindowHandle #-> "11803692"
    Write-Host $p.Handle #-> "3080"

    ---結果---

    メインウィンドウ
    11803692(これはHEXで00B41C2C なので、Spy++と一致)
    3080

    ----------

    ■質問1

    $pには、プロセス名から取得したプロセスオブジェクトが入っている認識ですが

    Handle(DEC:3080  HEX:C08)には何が入っているのでしょうか。

    ■質問2

    $p から、MyApp2のタイトルやその子コントロールを得る事方法について

    PowerShellの列挙を記載する方法のみで可能なものでしょうか。

    それとも、EnumChildWindows といったCOM呼び出しをC#などで定義した上で

    子ウィンドウを列挙させるような方法しか実現できないのでしょうか。

    やりたいことをお伝えするための言葉選びが難しいのですが、Scriptの冒頭や、外部呼び出しで他のCOM呼び出しを行わずに、

    トップレベルのウィンドウから子ウィンドウの列挙が可能かを知りたいというものです。

    例えばこんな感じで、何かの方法でアクセスできるのかというものです。

    $p.Handles | ForEach-Object { Write-Host $_ }


    お手数をおかけいたしますが、よろしくお願い致します。



    • 編集済み Unripe01 2018年7月13日 8:29 句読点を一部削除
    2018年7月13日 8:25

回答

  • Get-Processコマンドレットは、System.Diagnostics.Processオブジェクトを返します。Processクラスに子ウィンドウを列挙する機能がない以上は、Get-Process単独では難しいのではないかと思います。

    ご提示されているEnumChildWindows関数などをC#で呼び出す(P/Invoke)クラスを作成し、そのクラスをPowerShellから呼び出すという方法になるかと思います。

    Add-Typeコマンドレットを用いれば、C#のコードを文字列としてスクリプトファイルに埋め込み、コンパイルしクラスとしてロードすることが可能です。

    • 回答としてマーク Unripe01 2018年7月16日 14:52
    2018年7月13日 9:17
    モデレータ

すべての返信

  • Get-Processコマンドレットは、System.Diagnostics.Processオブジェクトを返します。Processクラスに子ウィンドウを列挙する機能がない以上は、Get-Process単独では難しいのではないかと思います。

    ご提示されているEnumChildWindows関数などをC#で呼び出す(P/Invoke)クラスを作成し、そのクラスをPowerShellから呼び出すという方法になるかと思います。

    Add-Typeコマンドレットを用いれば、C#のコードを文字列としてスクリプトファイルに埋め込み、コンパイルしクラスとしてロードすることが可能です。

    • 回答としてマーク Unripe01 2018年7月16日 14:52
    2018年7月13日 9:17
    モデレータ
  • ご回答いただきありがとうございます。

    なるほど、Power Shell単体で考えるのではなく、コマンドレットが返す型を意識いすれば答えに辿り着けたわけですね。

    質問1についても調べられそうです。

    ありがとうございました。

    2018年7月16日 14:54