質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

起動中のMicrosoft EdgeからタイトルとURLを取得したい(C# or VB.NET)

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,736

score 6

 前提・実現したいこと

お世話になります。

本ソースはこちらを参考にWindowsフォームで検証中です。
https://teratail.com/questions/88664

 発生している問題・エラーメッセージ

①タブの情報が取得できない
②Edgeが最小化されている場合そもそも取得できない

 該当のソースコード

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UIAutomationClient;

namespace GetEdgeUrl
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello World!!", btnTest.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            GetTrialEdgeUrl02();

        }

        private void GetTrialEdgeUrl02()
        {
            string CLSID_CUIAutomation = "ff48dba4-60ef-4201-aa87-54103eef594e";
            Type type = Type.GetTypeFromCLSID(Guid.Parse(CLSID_CUIAutomation));
            IUIAutomation automation = Activator.CreateInstance(type) as IUIAutomation;

            IUIAutomationElement root = automation.GetRootElement();
            IUIAutomationTreeWalker walker = automation.RawViewWalker;

            IUIAutomationElement edge = null;
            //IUIAutomationElementArray edgeAry = null;

            edge = walker.GetFirstChildElement(root);
            while (edge != null)
            {
                string name = edge.CurrentName;
                if (!string.IsNullOrEmpty(name) && name.EndsWith(" ‎- Microsoft Edge"))
                {
                    //break;
                    //Edge配下のタイトルが取得できそうなエレメントを取得
                    IUIAutomationElement m_tabContentDCompVisualElement = null;
                    {
                        const int UIA_AutomationIdPropertyId = 30011;
                        var cond = automation.CreatePropertyCondition(UIA_AutomationIdPropertyId,
                            "m_tabContentDCompVisualElement");
                        m_tabContentDCompVisualElement = edge.FindFirst(TreeScope.TreeScope_Subtree, cond);

                    }

                    if (m_tabContentDCompVisualElement == null)
                    {
                        //MessageBox.Show("Edgeが起動していません。", btnExecute.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }

                    //タイトル
                    string title = m_tabContentDCompVisualElement.CurrentName;

                    //Edge配下のURLが取得できそうなエレメントを取得
                    IUIAutomationElement ie_server;
                    {
                        const int UIA_ClassNamePropertyId = 30012;
                        var cond = automation.CreatePropertyCondition(UIA_ClassNamePropertyId, "Internet Explorer_Server");
                        ie_server = edge.FindFirst(TreeScope.TreeScope_Subtree, cond);

                    }

                    if (ie_server == null)
                    {
                        return;
                    }

                    //URL
                    string url = ie_server.CurrentName;

                    StringBuilder MsgLine = new StringBuilder();
                    MsgLine.Append("Title:");
                    MsgLine.AppendLine(title);
                    MsgLine.Append("Url:");
                    MsgLine.AppendLine(url);

                    MessageBox.Show(MsgLine.ToString(), btnExecute.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
                IUIAutomationElement next = walker.GetNextSiblingElement(edge);
                edge = next;
            }
            if (edge == null)
            {
                MessageBox.Show("Edgeが起動していません。", btnExecute.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }



            //Console.WriteLine(title);
            //Console.WriteLine(url);
            //Console.ReadKey();
        }
    }
}

 試したこと

IUIAutomationElementArrayを使えばいいのかなと思ったのですが、
うまくいかず…

 補足情報(FW/ツールのバージョンなど)

Microsoft Visual Studio Professional 2017
Version 15.6.5
Microsoft .NET Framework
Version 4.7.02556
Microsoft Edge 41.16299.248.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

下記で一旦解決しました。
※UIAutomationClientの利用を辞めました。

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

namespace GetEdgeUrl02
{
    public partial class frmMain : Form
    {
        [Flags]
        private enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008,
            SMTO_ERRORONEXIT = 0x0020
        }
        private delegate bool Win32Callback(IntPtr hWnd, ref IntPtr lParam);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumWindows(Win32Callback lpEnumFunc, ref IntPtr lParam);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        [DllImport("oleacc.dll", PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern uint RegisterWindowMessage(string lpString);
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out UIntPtr result);
        // ■取得確認用フラグ
        private bool NoneFlg;

        public frmMain()
        {
            InitializeComponent();
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            this.NoneFlg = false;
            IntPtr hWin = IntPtr.Zero;
            Win32Callback proc = new Win32Callback(EnumWindowsProc);
            EnumWindows(proc, ref hWin);
            // ■取得しなかった場合
            if (this.NoneFlg == false) {
                MessageBox.Show("Edgeが起動していません。", this.btnExecute.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

        }
        private bool EnumWindowsProc(IntPtr hWnd, ref IntPtr lParam)
        {
            IntPtr hChild = IntPtr.Zero;
            StringBuilder buf = new StringBuilder(1024);
            GetClassName(hWnd, buf, buf.Capacity);
            if (buf.ToString() == "TabWindowClass")
            {
                //get 'Internet Explorer_Server' window
                hChild = FindWindowEx(hWnd, IntPtr.Zero, "Internet Explorer_Server", "");
                if (hChild != IntPtr.Zero)
                {
                    dynamic doc = null;
                    doc = GetHTMLDocumentFromWindow(hChild);
                    if (doc != null)
                    {
                        // ■メッセージボックスで返却
                        //Console.WriteLine(doc.Title + ", " + doc.url); //get document title & url
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("Title:" + doc.Title);
                        sb.AppendLine("Url:" + doc.url);
                        MessageBox.Show(sb.ToString(), "Ante-Mode", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.NoneFlg = true;
                    }
                }
            }
            return true;
        }

        //get HTMLDocument object
        private static object GetHTMLDocumentFromWindow(IntPtr hWnd)
        {
            UIntPtr lRes;
            object doc = null;
            Guid IID_IHTMLDocument2 = new Guid("332C4425-26CB-11D0-B483-00C04FD90119");
            uint nMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
            if (nMsg != 0)
            {
                SendMessageTimeout(hWnd, nMsg, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out lRes);
                if (lRes != UIntPtr.Zero)
                {
                    doc = ObjectFromLresult(lRes, IID_IHTMLDocument2, IntPtr.Zero);
                }
            }
            return doc;
        }

    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る