使用 C++ 在 FireFox 中获取活动选项卡 URL
Get active Tab URL in FireFox with C++
我正在尝试使用 UI 自动化从 Firefox 获取 URL,但它总是失败。
它在 Chrome 中运行良好。但它在 Firefox 中不起作用。
我认为搜索或输入地址与 Chrome
中的 'Address and search bar' 相同
#include <Windows.h>
#include <AtlBase.h>
#include <AtlCom.h>
#include <UIAutomation.h>
#include <stdlib.h>
#define UNICODE
int main()
{
CoInitialize(NULL);
HWND hwnd = NULL;
while (true)
{
hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
if (!hwnd)
break;
if (!IsWindowVisible(hwnd))
continue;
CComQIPtr<IUIAutomation> uia;
if (FAILED(uia.CoCreateInstance(CLSID_CUIAutomation)) || !uia)
break;
CComPtr<IUIAutomationElement> root;
if (FAILED(uia->ElementFromHandle(hwnd, &root)) || !root)
break;
CComPtr<IUIAutomationCondition> condition;
uia->CreatePropertyCondition(UIA_ControlTypePropertyId,
CComVariant(0xC354), &condition);
CComPtr<IUIAutomationElement> edit;
if (FAILED(root->FindFirst(TreeScope_Descendants, condition, &edit))
|| !edit)
continue; //maybe we don't have the right tab, continue...
CComVariant url;
edit->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url);
MessageBox(0, url.bstrVal, 0, 0);
break;
}
CoUninitialize();
return 0;
}
消息框中显示空白值
我想获取活动选项卡 URL
以上代码的主要部分设计用于 Chrome,而不是 Firefox。
使用 Inspect 工具检查 Firefox 中的控件排列。您将看到类似以下结构的内容:
Firefox window
-> "" toobar
-> "" toobar
-> "Navigation Toolbar" toobar
-> "" combobox
-> "Search with Google" edit //<- url editbox
-> "Search" combobox //<- we don't want this
我们需要带有标签“Search with Google”的控件。我们可以按名称查找元素,但这可能取决于语言,控件的顺序也可能不同,因为用户可以自定义浏览器并重新排列控件。
相反,我们可以查找 AutomationId
,在这种情况下,它在 Firefox 中可用(并非总是如此)
“导航”显示AutomationId = "nav-bar"
属性,“编辑框”显示AutomationId = "urlbar-input"
属性
我们可以使用UIA_AutomationIdPropertyId
来查找这些名字:
int main()
{
if FAILED(CoInitialize(nullptr))
return 0;
struct coinit { ~coinit() { CoUninitialize(); } } cleanup;
//find the first visible window in firefox
HWND hwnd = NULL;
while (true)
{
hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
if (!hwnd)
return 0;
if (IsWindowVisible(hwnd))
break;
}
//initialize UIAutomation
CComPtr<IUIAutomation> uia;
if FAILED(uia.CoCreateInstance(CLSID_CUIAutomation))
return 0;
CComPtr<IUIAutomationElement> root, navigation, editbox;
CComPtr<IUIAutomationCondition> c1, c2;
//find root from hwnd handle
if FAILED(uia->ElementFromHandle(hwnd, &root))
return 0;
//find navigation bar as child of root
uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
CComVariant(L"nav-bar"), &c1);
if FAILED(root->FindFirst(TreeScope_Children, c1, &navigation))
return 0;
//find editbox under as descendant of navigation
uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
CComVariant(L"urlbar-input"), &c2);
if FAILED(navigation->FindFirst(TreeScope_Descendants, c2, &editbox))
return 0;
//get the string in editbox
CComVariant url;
if FAILED(editbox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url))
return 0;
if(url.bstrVal)
wprintf(L"[%s]\n", url.bstrVal);
return 0;
}
我正在尝试使用 UI 自动化从 Firefox 获取 URL,但它总是失败。
它在 Chrome 中运行良好。但它在 Firefox 中不起作用。 我认为搜索或输入地址与 Chrome
中的 'Address and search bar' 相同#include <Windows.h>
#include <AtlBase.h>
#include <AtlCom.h>
#include <UIAutomation.h>
#include <stdlib.h>
#define UNICODE
int main()
{
CoInitialize(NULL);
HWND hwnd = NULL;
while (true)
{
hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
if (!hwnd)
break;
if (!IsWindowVisible(hwnd))
continue;
CComQIPtr<IUIAutomation> uia;
if (FAILED(uia.CoCreateInstance(CLSID_CUIAutomation)) || !uia)
break;
CComPtr<IUIAutomationElement> root;
if (FAILED(uia->ElementFromHandle(hwnd, &root)) || !root)
break;
CComPtr<IUIAutomationCondition> condition;
uia->CreatePropertyCondition(UIA_ControlTypePropertyId,
CComVariant(0xC354), &condition);
CComPtr<IUIAutomationElement> edit;
if (FAILED(root->FindFirst(TreeScope_Descendants, condition, &edit))
|| !edit)
continue; //maybe we don't have the right tab, continue...
CComVariant url;
edit->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url);
MessageBox(0, url.bstrVal, 0, 0);
break;
}
CoUninitialize();
return 0;
}
消息框中显示空白值 我想获取活动选项卡 URL
以上代码的主要部分设计用于 Chrome,而不是 Firefox。
使用 Inspect 工具检查 Firefox 中的控件排列。您将看到类似以下结构的内容:
Firefox window
-> "" toobar
-> "" toobar
-> "Navigation Toolbar" toobar
-> "" combobox
-> "Search with Google" edit //<- url editbox
-> "Search" combobox //<- we don't want this
我们需要带有标签“Search with Google”的控件。我们可以按名称查找元素,但这可能取决于语言,控件的顺序也可能不同,因为用户可以自定义浏览器并重新排列控件。
相反,我们可以查找 AutomationId
,在这种情况下,它在 Firefox 中可用(并非总是如此)
“导航”显示AutomationId = "nav-bar"
属性,“编辑框”显示AutomationId = "urlbar-input"
属性
我们可以使用UIA_AutomationIdPropertyId
来查找这些名字:
int main()
{
if FAILED(CoInitialize(nullptr))
return 0;
struct coinit { ~coinit() { CoUninitialize(); } } cleanup;
//find the first visible window in firefox
HWND hwnd = NULL;
while (true)
{
hwnd = FindWindowEx(0, hwnd, L"MozillaWindowClass", NULL);
if (!hwnd)
return 0;
if (IsWindowVisible(hwnd))
break;
}
//initialize UIAutomation
CComPtr<IUIAutomation> uia;
if FAILED(uia.CoCreateInstance(CLSID_CUIAutomation))
return 0;
CComPtr<IUIAutomationElement> root, navigation, editbox;
CComPtr<IUIAutomationCondition> c1, c2;
//find root from hwnd handle
if FAILED(uia->ElementFromHandle(hwnd, &root))
return 0;
//find navigation bar as child of root
uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
CComVariant(L"nav-bar"), &c1);
if FAILED(root->FindFirst(TreeScope_Children, c1, &navigation))
return 0;
//find editbox under as descendant of navigation
uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
CComVariant(L"urlbar-input"), &c2);
if FAILED(navigation->FindFirst(TreeScope_Descendants, c2, &editbox))
return 0;
//get the string in editbox
CComVariant url;
if FAILED(editbox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url))
return 0;
if(url.bstrVal)
wprintf(L"[%s]\n", url.bstrVal);
return 0;
}