You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual C++报Debug Assertion Failed错误,获取Firefox标签页URL失败如何解决

问题复现

运行时弹出Debug Assertion Failed! Visual C++错误,错误截图如下:
我的错误代码

核心报错点
  • 尝试用__try捕获异常时报错:Cannot use __try in functions that require object unwinding
  • 关闭异常抛出模式后,错误定位到代码行:
if FAILED(navigation->FindFirst(TreeScope_Descendants, c2, &editbox))
问题原因
  1. __try是MSVC提供的结构化异常处理(SEH)语法,和C++的栈自动析构逻辑不兼容。你的函数内包含CComPtr智能指针、自定义的coinit析构结构体这类需要自动执行析构的对象,编译器会直接禁止在这类函数内使用__try语法,避免出现内存泄漏。
  2. 你代码中所有COM调用的FAILED判断仅打印日志,没有中断执行逻辑。如果前面root->FindFirst查找导航栏失败,navigation会是空指针,后续直接调用空指针的FindFirst方法就会触发断言错误。
修复方案

1. 替换__try异常捕获逻辑

不要使用SEH的__try,改用C++标准的try/catch即可。如果一定要用SEH,可以把需要捕获异常的逻辑抽成单独的子函数,子函数内不要定义任何需要自动析构的局部对象,再在getURL中调用该子函数。

2. 补全错误中断逻辑

每一步COM调用判断失败后直接返回错误值,不要继续执行后续逻辑,修改后的完整参考代码:

char* getURL() {
    char* urlstr = (char*)"None";
    if (FAILED(CoInitialize(nullptr))) {
        cout << "CoInitialize error..." << endl;
        return urlstr;
    }
    struct coinit { ~coinit() { CoUninitialize(); } } cleanup;
    // 查找第一个可见的火狐窗口
    HWND hwnd = NULL;
    while (true)
    {
        hwnd = FindWindowEx(0, hwnd, "MozillaWindowClass", NULL);
        if (!hwnd)
            return urlstr;
        if (IsWindowVisible(hwnd))
            break;
    }
    // 初始化UIAutomation
    CComPtr<IUIAutomation> uia;
    if (FAILED(uia.CoCreateInstance(CLSID_CUIAutomation))) {
        cout << "UIAutomation实例创建失败" << endl;
        return urlstr;
    }
    CComPtr<IUIAutomationElement> root, navigation, editbox;
    CComPtr<IUIAutomationCondition> c1, c2;
    // 从窗口句柄获取根元素
    if (FAILED(uia->ElementFromHandle(hwnd, &root))) {
        cout << "获取窗口根元素失败" << endl;
        return urlstr;
    }
    // 查找导航栏
    uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
        CComVariant(L"nav-bar"), &c1);
    if (FAILED(root->FindFirst(TreeScope_Children, c1, &navigation)) || navigation == nullptr) {
        cout << "未找到导航栏" << endl;
        return urlstr;
    }
    // 查找地址栏输入框
    uia->CreatePropertyCondition(UIA_AutomationIdPropertyId,
        CComVariant(L"urlbar-input"), &c2);
    if (FAILED(navigation->FindFirst(TreeScope_Descendants, c2, &editbox)) || editbox == nullptr) {
        cout << "未找到地址栏输入框" << endl;
        return urlstr;
    }
    // 读取地址栏内容
    CComVariant url;
    if (FAILED(editbox->GetCurrentPropertyValue(UIA_ValueValuePropertyId, &url))) {
        cout << "读取地址栏内容失败" << endl;
        return urlstr;
    }
    if (url.bstrVal != NULL) {
        urlstr = _com_util::ConvertBSTRToString(url.bstrVal);
    }
    return urlstr;
}

3. 其他注意点

  • 如果你的项目是Unicode编码,FindWindowEx的窗口类名字符串要改成宽字符版本L"MozillaWindowClass",避免类型转换错误。
  • _com_util::ConvertBSTRToString返回的字符串是堆分配内存,调用getURL的一方用完后需要调用free释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者aiueo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:30:01