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

    【2017年3月版】Microsoft Edgeでブックマークレットを使う方法

    2015年8月にMicrosoft Edgeでブックマークレットを使う…

  2. Windows関連

    ドラッグ&ドロップした画像をクリップボードにコピーするバッチファイル

    いくつか画像ファイルを編集する必要があったときに書いたバッチ(というよ…

  3. Windows 10

    ストアアプリを起動するPowerShellコード

    ストアアプリ(UWPアプリ)は実行ファイルをダブルクリックする等して直…

  4. Office関連

    Microsoft Edgeを操作するVBAマクロ(WebDriver編)

    Microsoft Edge Dev Blogに「Bringing a…

  5. Windows関連

    [Windows 8]ログオン時にデスクトップを表示する。

    通常Windows 8はログオン時にスタートスクリーンが表示されますが…

コメント

  • コメント (0)

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

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

Time limit is exhausted. Please reload CAPTCHA.

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

Translate

最近の記事

アーカイブ

PAGE TOP