如何在Google Chrome/Chromium浏览器中获取Gmail附件文件名
Chrome/Chromium 环境下获取Gmail附件文件名实现方案
原有GTK方案的问题
你当前编写的GTK接口调用代码存在4个致命问题,会导致逻辑失效甚至程序崩溃:
- 遍历
GSList链表时没有推进迭代器(缺少it = it->next逻辑),会触发死循环 - 返回值为未初始化的野指针
ki,调用方拿到返回值后会触发非法内存访问 - 没有做符号地址有效性校验,若目标符号加载失败会直接触发段错误
- 未区分「hook接口替换原函数」和「主动调用接口」的场景,直接释放返回的链表会导致Chrome自身逻辑拿不到文件路径崩溃
可行实现路径
方案1:修正GTK文件选择器Hook(仅适配Linux原生GTK桌面环境)
该方案通过hook GTK文件选择器的获取文件名接口,在用户确认保存路径时拿到文件完整路径,再从路径中提取文件名。注意:该方案拿到的是用户最终保存的本地文件名,若用户手动修改了保存时的文件名,将无法获取Gmail附件的原始名称;且当Chrome使用XDG桌面门户文件选择器、Qt/其他UI后端选择器时该方案会失效。
修正后的代码示例:
#include <gtk/gtk.h> #include <glib.h> // 自行实现的动态符号地址获取函数 extern void* gtkFunctionAddr(const char* func_name); GSList* gtk_file_chooser_get_filenames(GtkFileChooser* chooser) { using RealFunc = GSList* (*)(GtkFileChooser*); static RealFunc real_get_filenames = nullptr; if (!real_get_filenames) { real_get_filenames = reinterpret_cast<RealFunc>(gtkFunctionAddr("gtk_file_chooser_get_filenames")); if (!real_get_filenames) { return nullptr; } } GSList* file_list = real_get_filenames(chooser); // 遍历所有选中的文件 for (GSList* it = file_list; it != nullptr; it = g_slist_next(it)) { const char* full_save_path = static_cast<const char*>(it->data); if (full_save_path) { // 从完整路径提取文件名 char* attach_name = g_path_get_basename(full_save_path); printf("Gmail附件保存文件名: %s\n", attach_name); g_free(attach_name); } } // 必须将原函数返回的链表交还给Chrome调用方,不能在此处释放,否则会导致Chrome崩溃 return file_list; }
如果是主动调用该接口获取文件名(而非hook替换原函数),使用完返回的链表后必须调用g_slist_free_full(file_list, g_free)释放内存,避免泄漏。
方案2:Hook Chromium下载内核接口(全平台通用,稳定性更高)
Gmail附件的原始文件名存储在HTTP响应的Content-Disposition头中,Chrome在弹出文件选择器之前就已经在下载模块完成了解析,直接从下载内核获取文件名不受UI后端、桌面环境、用户手动修改保存名的影响,是更可靠的方案:
- 针对对应版本的Chromium源码,hook
ChromeDownloadManagerDelegate::GenerateFilename或content::DownloadItemImpl的创建逻辑,入参中直接携带了解析完成的附件原始文件名、下载URL、文件大小等完整信息 - 该方案适配Windows、macOS、Linux全平台,不依赖GTK/Qt等任何桌面UI库,也不会因为Chrome切换Ozone、XDG门户等新的文件选择器实现而失效
注意事项
- 使用LD_PRELOAD方式hook GTK接口时,需要确保编译时的GTK版本、符号版本和目标系统的GTK库版本匹配
- 若需要获取未被用户修改的附件原始文件名,不要使用GTK层hook方案,必须从Chrome下载内核层获取数据
- 部分Linux发行版的Chrome/Chromium默认启用XDG桌面门户,文件选择器由独立的门户进程提供,此时GTK hook完全无法捕获到选择器事件
内容的提问来源于stack exchange,提问作者Rushikersh Office
相关产品推荐
相关产品推荐

