Windows 10

続・起動中のMicrosoft EdgeからタイトルとURLを取得するC#コード(UI Automation編)

2017/8/18 追記:
当記事のコードは現在動作しなくなっているため、新しくコードを書き直しました。


前回の記事で、UI Automationを使って起動中のMicrosoft EdgeからタイトルとURLを取得するC#コードを紹介しましたが、動作としてはEdgeのアドレス欄をフォーカスしてからURLを取得するという面倒なことをやっています。

それに対して「Microsoft Edge: Get Window URL and Title」では、ClassNameプロパティが「Internet Explorer_Server」のPaneコントロールからCachedNameプロパティを取得する形がとられています。

コードを見る限り、たしかにコチラの方が手間が無くて良いですね。
(実は私も「起動中のMicrosoft EdgeからタイトルとURLを取得するVBAマクロ(UI Automation編)」を書いたときに同じような方法を試したのですが、そのときは何故かURLが途中で切れてしまうページがあったので、結局アドレス欄から取得する方法にしました。)

ただ、一つ気になるのが下記の一文。

“The C# code uses a UIA interop dll that I generated through the tlbimp tool.”

えー!?Tlbimp.exeでわざわざDLL吐き出さないといけないの??
Visual Studio入れてない人はどうすれば良いの??

・・・というわけで、何とか別の方向から行けないか、調べてみることにしました。

まず、Inspectで先のPaneコントロールを調べたところ、NativeWindowHandleが0x1005CAになっていました。

AutomateMicrosoftEdge_UIA_Csharp_2_01

このウィンドウが何なのかをSpy++で調べたところ、「Windows.UI.Core.CoreComponentInputSource」クラスのウィンドウであることが分かりました。

AutomateMicrosoftEdge_UIA_Csharp_2_02

ということは、Edgeの子ウィンドウからWindows.UI.Core.CoreComponentInputSourceクラスのウィンドウを列挙して、そこからAutomationElementを捕まえれば良いのでは?

・・・ということで、さっそくやってみました。

※ UIAutomationClient, UIAutomationTypes 要参照

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Automation;

namespace UIAutomationEdge
{
  class Program
  {
    public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);
    [DllImport("user32.Dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static public extern IntPtr GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
    
    [DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)]
    public static extern IntPtr GetParent(IntPtr hWnd);
    
    public static void Main(string[] args)
    {
      AutomationElement root = AutomationElement.RootElement;
      AutomationElement edge = root.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "TitleBar"));
      if (edge != null) {
        edge = edge.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Windows.UI.Core.CoreWindow"));
        if (edge != null) {
          Win32Callback childProc = new Win32Callback(EnumWindow);
          EnumChildWindows((IntPtr)edge.Current.NativeWindowHandle, childProc, (IntPtr)0);
          Console.ReadKey(true);
        }
      }
    }
    
    private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
      StringBuilder buf = new StringBuilder(255);
      IntPtr ret = GetClassName(handle, buf, buf.Capacity);
      if (ret != IntPtr.Zero) {
        string className = buf.ToString();
        if (className == "Windows.UI.Core.CoreComponentInputSource") {
          IntPtr hTitle = GetParent(handle);
          AutomationElement title = AutomationElement.FromHandle(hTitle);
          AutomationElement url = AutomationElement.FromHandle(handle);
          Console.WriteLine(title.Current.Name + ", " + url.Current.Name);
        }
      }
      return true;
    }
  }
}

EnumChildWindowsでウィンドウを列挙してGetClassNameでクラス名を調べていくという、これはこれで面倒くさいものですが、一応下図の通り目的達成できました。

AutomateMicrosoftEdge_UIA_Csharp_2_03

起動中のMicrosoft EdgeからタイトルとURLを取得するC#コード(UI Automation編)前のページ

「microsoft-edge:」って何?次のページ

関連記事

  1. Windows 10

    [Windows 10]「コマンド ウィンドウをここで開く」を復元する方法

    この記事にあるように、これまではShiftキーを押しながらフォルダを右…

  2. Windows 10

    Windows Insider Meetup in Japan 2019 東京に参加しました。

    Windows Insider向けのミートアップイベント「Window…

  3. Windows関連

    Lhaplusのバージョンを取得するVBScript

    およそ2年ぶりに圧縮・解凍ソフトの「Lhaplus」がバージョンアップ…

  4. Office関連

    IEサポート終了でVBAマクロはどうなるの?(2)

    ※下記情報は2021年5月時点の情報で、今後状況が変わっていく可能性が…

  5. Windows 10

    「ファイル名を指定して実行」からMicrosoft Edgeを起動する

    以前書いた記事で、Microsoft EdgeをVBScriptから起…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP