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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Q&A

解決済

1回答

10895閲覧

Edge(chromium)の開いているタブを列挙する

trons

総合スコア20

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

1グッド

0クリップ

投稿2021/10/15 07:08

編集2021/10/15 09:06

お世話になります。
Edge複数プロセス、複数タブを開いた状態でWebDriverを使用せずに
開かれているタブ上のタイトルを列挙する方法を調べております。
(WebDriverを使用すれば、取得できるのは把握していますが、ドライバーを使用するには
常にローカルのEdgeバージョンと同じバージョンのドライバーが必要なため却下しました。)

MS製のSPY++(V12 2012年製なのでEdgeが出来る前です。)
で、確認すると、個別のタブの状態が表示されています。
イメージ説明
クラス名:Windows.Internal.Shell.TabProxyWindow

~~自作コードや、~~SPYの代替品でなどで調べると、SPYとは異なる表示となり
表示されているタブをまとめた形で表示されます。

◆Windows10のウィンドウ構成要素を2種類の方法で列挙するツールを作ってみた
[https://qiita.com/kob58im/items/3587d8e595e655e9391d]
イメージ説明
クラス名:Chrome_WidgetWin_1

また、UIAUTOMATIONで列挙する方法もありますが、この場合Edgeのプロセスが複数ある場合
アクティブのプロセスのみ取得できる形となり、都度対象Edgeをアクティブにする必要が発生するため
こちらも却下としました。
◆How to get a list of open tabs from chrome? | C#
リンク内容

古いSPYでも欲しい情報が取れているので、何らかの方法で取得が可能だと考えておりますが
その方法が分からず困っております。

タブの実態?のクラス名「Chrome_WidgetWin_1」 や「TabProxyWindow」で検索すると
取得は出来ているようなので、なんらかの方法により実現は可能では無いかと考えております。
リンク内容
リンク内容

何卒宜しくお願い致します。

TN8001👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/10/15 07:25

何を問題にされているかか少々分かりづらいようです。 > 自作コードや、SPYの代替品でなどで調べると、SPYとは異なる表示されているタブをまとめた形でで表示されます。 その自作のコードで、まとめ"ない"ようにすればよい話なのではないでしょうか? まとめないようにできるかできないかは、そのコードを提示しないと第三者には分からないと思います。 SPY++での表示は恐らく「デスクトップウィンドウを親とした"Windows.Internal.Shell.TabProxyWindow"クラスのウィンドウで、ウィンドウスタイルがWS_OVERLAPPEDを持っているものをEnumWindows APIなどで列挙しているのだと思います。あくまで推測ですが。
Zuishin

2021/10/15 07:54

一般に自作というのは自分で作ったものを言いますが、ここではどういう意味で使われていますか?
trons

2021/10/15 09:03

dodox86さま >その自作のコードで、まとめ"ない"ようにすればよい話なのではないでしょうか? >まとめないようにできるかできないかは、そのコードを提示しないと第三者には分からないと思います。 ◆Windows10のウィンドウ構成要素を2種類の方法で列挙するツールを作ってみた [https://qiita.com/kob58im/items/3587d8e595e655e9391d] こちらのリンクの様にタブがまとまった形で表示されます。 これは、他のサイトで公開されているSPYモドキでも同様の動きとなります。 ◆How can I get functionality similar to Spy++ in my C# app? [https://stackoverflow.com/questions/1967604/how-can-i-get-functionality-similar-to-spy-in-my-c-sharp-app] 上記を実行すると process msedge 3e08 window 10612 text:C# - Edge(chromium)の開いているタブを列挙する|teratail および他 3 ページ - 個人 - Microsoft? Edge caption: window 10618 text: caption: window 3b0ce8 text:Chrome Legacy Window caption:Chrome Legacy Window window 1306e2 text:Chrome Legacy Window caption:Chrome Legacy Window window 2c0cd4 text:Chrome Legacy Window caption:Chrome Legacy Window window a08b6 text:Chrome Legacy Window caption:Chrome Legacy Window window 53077a text:Chrome Legacy Window caption:Chrome Legacy Window window 2a0a36 text:Chrome Legacy Window caption:Chrome Legacy Window window e0840 text:Chrome Legacy Window caption:Chrome Legacy Window window 40a30 text:Chrome Legacy Window caption:Chrome Legacy Window window 406d8 text:Chrome Legacy Window caption:Chrome Legacy Window window a06de text:Chrome Legacy Window caption:Chrome Legacy Window window 10610 text: caption: window 5047a text: caption: window 20608 text: caption: window 10602 text: caption: window f08b8 text:How to get a list of open tabs from chrome? | C# - Stack Overflow および他 5 ページ - 個人 - Microsoft? Edge caption: window 1061a text:MSCTFIME UI caption: window 10604 text:Default IME caption: process Microsoft.ServiceHub.Controller 2168 上記のように各プロセス毎にタブがまとまった形で表示されます。 この際、SPYとは異なり、クラス名が「Chrome_WidgetWin_1となります。」 書いたコードも、上記のHPなどのコードを元にクラス名などの情報を列挙するようにした物なので 根本的な挙動は同じとなります。 >SPY++での表示は恐らく「デスクトップウィンドウを親とした"Windows.Internal.Shell.TabProxyWindow"クラスのウィンドウで、ウィンドウスタイルがWS_OVERLAPPEDを持っているものをEnumWindows APIなどで列挙しているのだと思います。あくまで推測ですが。 "Windows.Internal.Shell.TabProxyWindow"クラスはGoogle等で2021年の内容しかHitしないので、2012年製のSPY++で クラス名で検索していないのではないかと考えています。 TabProxyWindowで検索 [https://www.google.co.jp/search?q=TabProxyWindow&sxsrf=AOaemvJQlWirikcJlqi90mCmFk-9aNXAJQ%3A1634287648542&source=hp&ei=IEBpYZuwHsrc-gSLs7SgCA&iflsig=ALs-wAMAAAAAYWlOMGkG_DqC6Y4_AVKbePdc2ujp-zsi&ved=0ahUKEwibwP_1g8zzAhVKrp4KHYsZDYQQ4dUDCAk&uact=5&oq=TabProxyWindow&gs_lcp=Cgdnd3Mtd2l6EAMyBAgjECcyBAgjECcyBAgjECdQzwRYzwRgtwpoAHAAeACAAWuIAWuSAQMwLjGYAQCgAQKgAQE&sclient=gws-wiz] 検索に引っかからないのでどのような方法かは不明ですが、もっと汎用的にSpy++は作成されているのでは無いかと思われます。 いずれにせよ、SPY++がどのような方法で情報を取得しているのかは不明ですが、クラス名:Windows.Internal.Shell.TabProxyWindowの情報が 列挙できれば問題が解決するのではないかと考えおりますが、その方法が不明です。
Zuishin

2021/10/15 09:23

で、一般に自作というのは自分で作ったものを言いますが、ここではどういう意味で使われていますか?
TN8001

2021/10/15 09:46

> (WebDriverを使用すれば、取得できるのは把握していますが、ドライバーを使用するには 常にローカルのEdgeバージョンと同じバージョンのドライバーが必要なため却下しました。) 自動取得に面倒なことは何もないですが。 [C# - C# WebDriverManagerで、今インストールされてるEdgeのバージョンに合わせてEdgeDriverをセットアップする|teratail](https://teratail.com/questions/356826 > SPYとは異なる表示となり > 表示されているタブをまとめた形で表示されます。 たしかにEnumWindowsでもEnumDesktopWindowsでも、アクティブタブ以外は出ないですね。 InspectのMSAA Modeだと、Spyとわりと近い感じで出ます。 アンドキュメントな方法のようですが、こちらの方は取れてるっぽいです。 [5月 | 2021 | Frost Moon Project | Diary](http://frostmoon.sakura.ne.jp/diary/archives/date/2021/05
guest

回答1

0

ベストアンサー

わかりました!!
マニフェストにdisableWindowFilteringの設定がいるようです。
c++ - How to get a relational window tree like Spy++ does? - Stack Overflow
アプリケーションマニフェスト - Win32 apps | Microsoft Docs

DllImportを書くのが面倒だったため↓を使用しました(使わない場合NativeMethods.txtは不要)
NuGet Gallery | Microsoft.Windows.CsWin32 0.1.588-beta

重要なのはapp.manifestです。他は好きにしてください。

cs

1using System; 2using System.Runtime.Versioning; 3using Windows.Win32; 4using Windows.Win32.Foundation; 5 6namespace Questions364547 7{ 8 class Program 9 { 10 static void Main() 11 { 12 if (OperatingSystem.IsWindowsVersionAtLeast(5)) 13 { 14 PInvoke.EnumWindows(CallBack, 0); 15 } 16 } 17 18 [SupportedOSPlatform("windows5.0")] 19 static BOOL CallBack(HWND handle, LPARAM param1) 20 { 21 unsafe 22 { 23 fixed (char* chars = new char[256]) 24 { 25 if (PInvoke.GetClassName(handle, chars, 256) == 0) return true; 26 27 if (new string(chars) != "Windows.Internal.Shell.TabProxyWindow") 28 return true; 29 } 30 31 var size = PInvoke.GetWindowTextLength(handle) + 1; 32 fixed (char* chars = new char[size]) 33 { 34 if (PInvoke.GetWindowText(handle, chars, size) == 0) return true; 35 36 Console.WriteLine($"タイトル: {new string(chars)}"); 37 } 38 39 return true; 40 } 41 } 42 } 43}

xml:app.manifest

1<?xml version="1.0" encoding="utf-8"?> 2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> 3 4 <asmv3:application> 5 <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2011/WindowsSettings"> 6 <disableWindowFiltering>true</disableWindowFiltering> 7 </asmv3:windowsSettings> 8 </asmv3:application> 9 10</assembly>

txt:NativeMethods.txt

1EnumWindows 2GetClassName 3GetWindowText 4GetWindowTextLength

投稿2021/10/17 03:15

編集2023/07/29 07:19
TN8001

総合スコア9321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

trons

2021/10/18 02:04

ありがとうございます。 期待する通りの動きとなりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問