ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WeFlow 第三方可插拔组件接口详解:WCDB 动态库、媒体解密插件与 WeLive 导出引擎的接入协议

WeFlow 第三方可插拔组件接口详解:WCDB 动态库、媒体解密插件与 WeLive 导出引擎的接入协议 【免费下载链接】WeFlowWeFlow - 一个本地的微信聊天记录导出和年度报告应用项目地址https://gitcode.com/gh_mirrors/wefl/WeFlow点击查看免费下载WeFlow 是一个本地的微信聊天记录导出与年度报告应用。为规避自带闭源数据解析实现所带来的来源与合规风险它不内置任何用于读取/解密本地数据的原生组件而是将 WCDB 数据库读取、DAT 媒体解密、会话批量导出等四类底层能力全部开放为「第三方可插拔组件」由用户在「设置 - 数据库 - 第三方组件路径」中自行指定可执行文件、动态库或插件路径应用只按既定协议与其交互。阅读本文你将完整掌握这三类组件的接口契约、加载/调用流程、JSON 数据载荷约定与故障诊断方法能够独立实现或对接一套可被 WeFlow 识别的第三方组件。本文档规范对应 docs/third-party-components.md所有接口细节均有 electron/services/wcdbCore.ts、electron/services/nativeImageDecrypt.ts、electron/services/weliveBridge.ts 三份源码实现作为依据。设计总则无内置、无校验、无降级在开始介绍具体接口前需要先理解 WeFlow 对第三方组件的基本策略它决定了后续所有接口的行为边界不内置任何原生组件。应用本体只包含纯 JS/TS 层的解析与导出框架凡是涉及本地数据库读取、图片/视频解密等闭源能力一律通过外部组件完成。只认路径不做校验。应用仅读取用户在设置中配置的路径并按下述协议与对应组件交互不验证组件的来源、数字签名或实现方式因此安全性完全取决于用户自选的组件实现。无降级替代。配置留空、或指向的文件不存在时对应功能直接返回「未配置」错误不会有任何降级实现或内置兜底方案。可选符号不阻塞。除少数必须存在的入口函数外其余函数均可按需实现缺失的符号只会让对应功能在应用里表现为「不可用」不影响其他已实现的功能。从源码可以印证这一策略resolveWeliveExecutable()在 weliveBridge.ts 中直接返回null注释明确说明「不再随应用内置查找仅认调用方显式传入的 welivePath」wcdbCore.ts中getDllPath()electron/services/wcdbCore.ts只从显式设置或环境变量WCDB_DLL_PATH获取路径找不到时初始化直接失败。一、WCDB 实现wcdbLibPathC ABI 动态库wcdbLibPath指向一个动态库Windows*.dll/ macOS*.dylib/ Linux*.so由 WeFlow 通过 koffi 以 C ABI 方式加载用于读取本地 SQLCipher 数据库提供会话、消息、联系人、群组、朋友圈SNS、媒体等全方位查询能力。加载流程WCDB 组件的加载逻辑集中在WcdbCore.initialize()electron/services/wcdbCore.ts实际流程如下通过koffi.load(wcdbLibPath)加载动态库本体。加载前会先按平台预加载同目录下的依赖库macOS 预加载libWCDB.dylibWindows 预加载WCDB.dll与SDL2.dll预加载失败仅告警不致命以保证动态库的符号依赖可以解析。依次尝试绑定约定的导出函数。每个函数用this.lib.func(...)声明若符号不存在则捕获异常并置为null该功能被跳过。第一个必须存在的函数是wcdb_open_account——它不绑定失败没有 try/catch 包裹其余函数全部可选缺失即对应功能不可用。初始化失败时通过getLastDllInitError()/getLastInitError()暴露错误信息界面侧可据此给出诊断提示。加载路径的解析优先级为setLibPath()显式设置的路径 环境变量WCDB_DLL_PATH 空失败。完整函数签名列表以下为 WCDB 动态库需要按 C ABI 导出的全部函数签名。约定如下int32返回值为状态码0表示成功_Out_ void** outJson类参数为调用方分配的字符串指针出参JSON 文本通过wcdb_free_string释放int64 handle为wcdb_open_account返回的数据库句柄其余标量参数含义见各签名注释。int32 wcdb_open_account(const char* path, const char* key, _Out_ int64* handle) int32 wcdb_close_account(int64 handle) int32 wcdb_init() int32 wcdb_shutdown() int32 wcdb_purge_memory() void wcdb_free_string(void* ptr) int32 wcdb_set_my_account_id(int64 handle, const char* accountId) int32 wcdb_get_sessions(int64 handle, _Out_ void** outJson) int32 wcdb_mark_all_sessions_read(int64 handle, _Out_ void** outError) int32 wcdb_reorder_sessions_by_time(int64 handle, _Out_ void** outJson) int32 wcdb_get_messages(int64 handle, const char* username, int32 limit, int32 offset, _Out_ void** outJson) int32 wcdb_get_messages_by_type(int64 handle, const char* sessionId, int64 localType, int32 ascending, int32 limit, int32 offset, _Out_ void** outJson) int32 wcdb_get_message_count(int64 handle, const char* username, _Out_ int32* outCount) int32 wcdb_get_message_by_id(int64 handle, const char* sessionId, int32 localId, _Out_ void** outJson) int32 wcdb_get_message_by_svrid(int64 handle, const char* sessionId, const char* svrid, _Out_ void** outJson) int32 wcdb_get_session_message_counts(int64 handle, const char* sessionIdsJson, _Out_ void** outJson) int32 wcdb_get_session_message_type_stats(int64 handle, const char* sessionId, int32 beginTimestamp, int32 endTimestamp, _Out_ void** outJson) int32 wcdb_get_session_message_type_stats_batch(int64 handle, const char* sessionIdsJson, const char* optionsJson, _Out_ void** outJson) int32 wcdb_get_session_message_date_counts(int64 handle, const char* sessionId, _Out_ void** outJson) int32 wcdb_get_session_message_date_counts_batch(int64 handle, const char* sessionIdsJson, _Out_ void** outJson) int32 wcdb_open_message_cursor(int64 handle, const char* sessionId, int32 batchSize, int32 ascending, int32 beginTimestamp, int32 endTimestamp, _Out_ int64* outCursor) int32 wcdb_fetch_message_batch(int64 handle, int64 cursor, _Out_ void** outJson, _Out_ int32* outHasMore) int32 wcdb_close_message_cursor(int64 handle, int64 cursor) int32 wcdb_set_message_cursor_projection(int64 handle, int64 cursor, int32 projection) int32 wcdb_search_messages(int64 handle, const char* sessionId, const char* keyword, int32 limit, int32 offset, int32 beginTimestamp, int32 endTimestamp, _Out_ void** outJson) int32 wcdb_ai_query_session_candidates(int64 handle, const char* optionsJson, _Out_ void** outJson) int32 wcdb_update_message(int64 handle, const char* sessionId, int64 localId, int32 createTime, const char* newContent, _Out_ void** outError) int32 wcdb_insert_text_message(int64 handle, const char* sessionId, const char* content, int64 status, int64 createTime, _Out_ void** outJson) int32 wcdb_delete_message(int64 handle, const char* sessionId, int64 localId, int32 createTime, const char* dbPathHint, _Out_ void** outError) int32 wcdb_check_message_anti_revoke_trigger(int64 handle, const char* sessionId, _Out_ int32* outInstalled) int32 wcdb_install_message_anti_revoke_trigger(int64 handle, const char* sessionId, _Out_ void** outError) int32 wcdb_uninstall_message_anti_revoke_trigger(int64 handle, const char* sessionId, _Out_ void** outError) int32 wcdb_get_contact(int64 handle, const char* username, _Out_ void** outJson) int32 wcdb_get_contact_status(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_contact_type_counts(int64 handle, _Out_ void** outJson) int32 wcdb_get_contacts_compact(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_contact_alias_map(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_contact_friend_flags(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_chat_room_ext_buffer(int64 handle, const char* chatroomId, _Out_ void** outJson) int32 wcdb_get_display_names(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_avatar_urls(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_head_image_buffers(int64 handle, const char* usernamesJson, _Out_ void** outJson) int32 wcdb_get_group_member_count(int64 handle, const char* chatroomId, _Out_ int32* outCount) int32 wcdb_get_group_member_counts(int64 handle, const char* chatroomIdsJson, _Out_ void** outJson) int32 wcdb_get_group_members(int64 handle, const char* chatroomId, _Out_ void** outJson) int32 wcdb_get_group_nicknames(int64 handle, const char* chatroomId, _Out_ void** outJson) int32 wcdb_get_group_stats(int64 handle, const char* chatroomId, int32 begin, int32 end, _Out_ void** outJson) int32 wcdb_get_aggregate_stats(int64 handle, const char* sessionIdsJson, int32 begin, int32 end, _Out_ void** outJson) int32 wcdb_get_available_years(int64 handle, const char* sessionIdsJson, _Out_ void** outJson) int32 wcdb_get_annual_report_stats(int64 handle, const char* sessionIdsJson, int32 begin, int32 end, _Out_ void** outJson) int32 wcdb_get_annual_report_extras(int64 handle, const char* sessionIdsJson, int32 begin, int32 end, int32 peakBegin, int32 peakEnd, _Out_ void** outJson) int32 wcdb_get_dual_report_stats(int64 handle, const char* sessionId, int32 begin, int32 end, _Out_ void** outJson) int32 wcdb_get_my_footprint_stats(int64 handle, const char* optionsJson, _Out_ void** outJson) int32 wcdb_get_message_tables(int64 handle, const char* sessionId, _Out_ void** outJson) int32 wcdb_get_message_table_stats(int64 handle, const char* sessionId, _Out_ void** outJson) int32 wcdb_get_message_dates(int64 handle, const char* sessionId, _Out_ void** outJson) int32 wcdb_get_message_meta(int64 handle, const char* dbPath, const char* tableName, int32 limit, int32 offset, _Out_ void** outJson) int32 wcdb_get_message_table_columns(int64 handle, const char* dbPath, const char* tableName, _Out_ void** outJson) int32 wcdb_get_message_table_time_range(int64 handle, const char* dbPath, const char* tableName, _Out_ void** outJson) int32 wcdb_list_tables(int64 handle, const char* kind, const char* dbPath, _Out_ void** outJson) int32 wcdb_get_table_schema(int64 handle, const char* kind, const char* dbPath, const char* tableName, _Out_ void** outJson) int32 wcdb_export_table_snapshot(int64 handle, const char* kind, const char* dbPath, const char* tableName, const char* outputPath, _Out_ void** outJson) int32 wcdb_import_table_snapshot(int64 handle, const char* kind, const char* dbPath, const char* tableName, const char* inputPath, _Out_ void** outJson) int32 wcdb_import_table_snapshot_with_schema(int64 handle, const char* kind, const char* dbPath, const char* tableName, const char* inputPath, const char* createTableSql, _Out_ void** outJson) int32 wcdb_list_message_dbs(int64 handle, _Out_ void** outJson) int32 wcdb_list_media_dbs(int64 handle, _Out_ void** outJson) int32 wcdb_get_media_schema_summary(int64 handle, const char* dbPath, _Out_ void** outJson) int32 wcdb_exec_query(int64 handle, const char* kind, const char* path, const char* sql, _Out_ void** outJson) int32 wcdb_get_emoticon_cdn_url(int64 handle, const char* dbPath, const char* md5, _Out_ void** outUrl) int32 wcdb_get_emoticon_caption(int64 handle, const char* dbPath, const char* md5, _Out_ void** outCaption) int32 wcdb_get_emoticon_caption_strict(int64 handle, const char* md5, _Out_ void** outCaption) int32 wcdb_get_voice_data(int64 handle, const char* sessionId, int32 createTime, int32 localId, int64 svrId, const char* candidatesJson, _Out_ void** outHex) int32 wcdb_get_voice_data_batch(int64 handle, const char* requestsJson, _Out_ void** outJson) int32 wcdb_resolve_image_hardlink(int64 handle, const char* md5, const char* accountDir, _Out_ void** outJson) int32 wcdb_resolve_image_hardlink_batch(int64 handle, const char* requestsJson, _Out_ void** outJson) int32 wcdb_resolve_video_hardlink_md5(int64 handle, const char* md5, const char* dbPath, _Out_ void** outJson) int32 wcdb_resolve_video_hardlink_md5_batch(int64 handle, const char* requestsJson, _Out_ void** outJson) int32 wcdb_scan_media_stream(int64 handle, const char* sessionIdsJson, int32 mediaType, int32 beginTimestamp, int32 endTimestamp, int32 limit, int32 offset, _Out_ void** outJson, _Out_ int32* outHasMore) int32 wcdb_get_sns_timeline(int64 handle, int32 limit, int32 offset, const char* username, const char* keyword, int32 startTime, int32 endTime, _Out_ void** outJson) int32 wcdb_get_sns_annual_stats(int64 handle, int32 begin, int32 end, _Out_ void** outJson) int32 wcdb_get_sns_usernames(int64 handle, _Out_ void** outJson) int32 wcdb_get_sns_export_stats(int64 handle, const char* myAccountId, _Out_ void** outJson) int32 wcdb_check_sns_block_delete_trigger(int64 handle, _Out_ int32* outInstalled) int32 wcdb_install_sns_block_delete_trigger(int64 handle, _Out_ void** outError) int32 wcdb_uninstall_sns_block_delete_trigger(int64 handle, _Out_ void** outError) int32 wcdb_delete_sns_post(int64 handle, const char* postId, _Out_ void** outError) int32 wcdb_start_monitor_pipe() void wcdb_stop_monitor_pipe() int32 wcdb_get_monitor_pipe_name(_Out_ void** outName) int32 wcdb_get_db_status(int64 handle, _Out_ void** outJson) int32 wcdb_get_logs(_Out_ void** outJson) int32 wcdb_cloud_init(int32 intervalSeconds) int32 wcdb_cloud_report(const char* statsJson) void wcdb_cloud_stop() void VerifyUser(int64 hwnd, const char* message, _Out_ char* outResult, int maxLen)函数分组与能力映射上述近百个函数可以按业务能力分成以下几组便于第三方实现者评估工作量与优先级能力域代表性函数对应应用场景生命周期wcdb_init/wcdb_shutdown/wcdb_open_account/wcdb_close_account/wcdb_purge_memory/wcdb_free_string加载、打开账号、释放资源会话wcdb_get_sessions/wcdb_mark_all_sessions_read/wcdb_reorder_sessions_by_time/wcdb_get_session_message_counts会话列表、已读、排序、角标消息wcdb_get_messages/wcdb_get_messages_by_type/wcdb_get_message_by_id/wcdb_get_message_by_svrid/wcdb_search_messages消息查询、搜索、定位消息统计wcdb_get_session_message_type_stats/wcdb_get_session_message_date_counts/wcdb_get_aggregate_stats/wcdb_get_annual_report_stats年度报告、双人报告、聊天分析游标分页wcdb_open_message_cursor/wcdb_fetch_message_batch/wcdb_close_message_cursor/wcdb_set_message_cursor_projection大规模消息流式读取写操作wcdb_update_message/wcdb_insert_text_message/wcdb_delete_message/ 防撤回触发器三件套消息编辑/发送/删除联系人wcdb_get_contact/wcdb_get_contacts_compact/wcdb_get_contact_alias_map/wcdb_get_contact_type_counts/wcdb_get_display_names/wcdb_get_avatar_urls联系人列表、备注、头像群组wcdb_get_group_members/wcdb_get_group_nicknames/wcdb_get_group_stats/wcdb_get_chat_room_ext_buffer群成员、群昵称、群统计数据表工具wcdb_list_tables/wcdb_get_table_schema/wcdb_get_message_meta/wcdb_exec_query/ 快照导入导出数据库体检、自定义 SQL、表备份媒体wcdb_get_voice_data/wcdb_get_voice_data_batch/wcdb_resolve_image_hardlink/wcdb_resolve_video_hardlink_md5/wcdb_scan_media_stream/ 表情/头图系列语音、图片、视频、表情资源解析朋友圈 SNSwcdb_get_sns_timeline/wcdb_get_sns_annual_stats/wcdb_get_sns_usernames/wcdb_delete_sns_post/ 防删触发器朋友圈时间线、SNS 导出监控与云上报wcdb_start_monitor_pipe/wcdb_get_monitor_pipe_name/wcdb_get_db_status/wcdb_get_logs/wcdb_cloud_init系列数据变化推送、状态诊断、统计上报JSON 载荷约定除少量_Out_ int32*/_Out_ int64*标量出参外大部分函数的出参为 JSON 字符串。文档明确JSON 载荷/出参的字段命名可直接参照wcdbCore.ts中每个函数调用点前后对返回值的解析逻辑。这是第三方实现者最权威的「字段字典」——先定位某个函数在 electron/services/wcdbCore.ts 中的调用处读取它对outJson的解析代码即可确认期望的 JSON 结构。此外多对象批量类函数如wcdb_get_contact_status(usernamesJson)、wcdb_get_session_message_type_stats_batch(sessionIdsJson, optionsJson)的入参为 JSON 数组/对象文本出参通常也是按同一维度组织 key 的 JSON内存管理遵循「调用方分配、wcdb_free_string释放」koffi侧在拿到void**出参后通过this.koffi.decode(ptr, char, -1)解码为 JS 字符串再用wcdbFreeString(ptr)释放参见 monitor pipe 名称的读取代码wcdbCore.ts。错误码与诊断信息initialize()失败时WcdbCore会将错误码翻译为用户可读的中文提示完整错误码表定义在formatInitProtectionError()electron/services/wcdbCore.ts主要分为几类未配置/环境类-1未配置 WCDB 实现-101/-1000系列提示关闭杀毒软件后重试-103第三方实现完整性校验失败-104检测到调试或分析环境-105离线防回拨状态损坏数据库打开类-3未找到 session.db-4数据库无法打开检查密钥/权限/损坏-5无法读取 schema-6无兼容会话表-7/-8/-9排序/最后消息时间字段缺失或冲突-10/-11会话统计失败运行时类-3001~-3004数据库目录/文件/句柄/连接问题-2301~-2303WCDB 初始化调用异常。这些错误信息可通过getLastDllInitError()/getLastInitError()取到供设置页或错误面板直接展示src/data/errorCatalog.ts 中亦有「第三方组件加载」阶段的错误分类。监控管道Monitor Pipewcdb_start_monitor_pipe/wcdb_stop_monitor_pipe/wcdb_get_monitor_pipe_name三个函数用于建立数据变化推送通道。从 wcdbCore.ts 的实现可以看到调用wcdb_start_monitor_pipe()后从wcdb_get_monitor_pipe_name获取动态管道名Windows 为\\.\pipe\weflow_monitor风格macOS 为 Unix Socket管道名通常含 PIDJS 侧通过net.createConnection连接管道按行读取 JSON 事件并交给monitorCallback(type, json)管道断开后每 3 秒自动重连scheduleReconnect并带「代次generation」机制防止旧连接干扰新会话传输层做了一级容错把\0归一化为换行、把}{拆包确保无分隔符或粘包场景下也能尽量还原完整 JSON 事件。二、媒体解密插件imageNativeAddonPathNode 原生插件imageNativeAddonPath指向一个 Node 原生插件.node通过require()加载对应 nativeImageDecrypt.ts 中定义的NativeAddon接口负责微信 DAT 加密图片/视频的解密。NativeAddon 接口定义{ decryptDatNative(inputPath: string, xorKey: number, aesKey?: string): { data: Buffer ext: string // 如 jpg/png/mp4不含点号也可 isWxgf?: boolean // 是否为 WXGF 容器格式是则会再走一层 unwrap version?: number aesSize?: number xorSize?: number rawSize?: number flag?: number } // 可选编辑/重新加密场景使用 encryptDatNative?(inputPath: string, xorKey: number, aesKey?: string, meta?: object): Buffer }字段约定ext可带点号也可不带JS 侧统一做toLowerCase()并补齐.前缀见 nativeImageDecrypt.tsisWxgf为true表示输出仍是 WXGF 容器格式调用方会再走一层 unwrap 处理aesSize/xorSize/rawSize/flag等元信息会被整理为NativeDatMeta返回支持蛇形与驼峰两种命名aes_size/aesSize均可encryptDatNative为可选导出用于编辑/重新加密场景返回加密后的Buffer未实现时相关功能会自然不可用。加载与调用机制加载逻辑nativeImageDecrypt.ts要点插件路径来自ConfigService.get(imageNativeAddonPath)也支持子线程通过setAddonPathOverride()显式传入因为 Worker 线程里electron-store可能不可用若路径包含app.asar会自动优先尝试app.asar.unpacked候选路径加载后校验decryptDatNative是否为函数是则缓存复用否则视为未配置返回null环境变量WEFLOW_IMAGE_NATIVE0可整体禁用原生解密。值得一提的是原生解密是同步 CPU/IO 调用滚动消息列表时批量触发会阻塞主线程因此 nativeImageDecrypt.ts 实现了Worker 化解密主线程通过decryptDatViaNativeAsync()把任务投递给imageDecryptWorker线程执行Worker 不可用时如模块缺失或永久失败自动回退为主线程同步解密行为与旧版一致。实现该插件时无需感知这一差异——插件本身只需导出符合NativeAddon接口的函数即可。文档还提示实现时可参照原始Wedecrypt/Rust 工程napi/napi-derivecdylib的技术路线复用其解密思路即可该工程不在当前仓库内仅作实现参考。三、WeLive 批量导出引擎welivePath可执行文件 NDJSON 协议welivePath指向一个独立可执行文件由 weliveBridge.ts 中的runWeliveExport()拉起用于会话的批量原始导出文本 媒体支持图片、语音、视频、表情、文件等媒体类型。协议采用「stdin 输入请求 JSON stdout 输出事件 NDJSON」的子进程交互模型。请求协议stdin启动命令为spawn(exe, [...weliveArgsPrefix, weflow-export])weliveBridge.ts即固定追加子命令weflow-export。随后把完整的WeliveExportRequest序列化为 JSON 写入子进程 stdin 并关闭。请求结构类型定义见 weliveBridge.ts{ account: { sessionDb: string // 会话数据库路径 dbKey: string // 数据库密钥 myAccountId?: string // 当前账号 ID accountDir?: string // 账号数据目录 imageXorKey?: string | number // 图片 DAT 的 XOR 密钥 imageAesKey?: string // 图片 DAT 的 AES 密钥如适用 }, sessionIds: string[], // 要导出的会话 ID 列表 outputDir: string, // 输出根目录 exportsDir?: string, // 原始导出目录 mediaDir?: string, // 媒体输出目录 mediaTypes?: Arrayimage | voice | video | emoji | file, emojiCacheDir?: string, formattedDir?: string, // 格式化导出目录 format?: string, preferredOutputPath?: string, parseContent?: boolean, compactRaw?: boolean, preserveMessageContent?: boolean, sanitize?: boolean, batchSize?: number, ascending?: boolean, options?: Recordstring, unknown // 扩展选项 }其中batchSize、ascending等字段用于控制分块导出的顺序与粒度options为扩展点可携带未来新增参数而不破坏协议兼容性。响应协议stdout NDJSON子进程通过 stdout按行输出WeliveExportEvent的 NDJSON。事件类型及字段类型定义见 weliveBridge.ts事件类型关键字段含义readytotal、output_dir、exports_dir、media_dir引擎就绪给出总量与输出目录progressphase、current、total、session_id、label、exported_messages、estimated_total_messages、phase_progress、phase_total进度上报支持多阶段进度created_filepath、session_id单个文件产出JS 侧据此记录会话输出路径created_dirpath目录创建session_errorsession_id、error单会话失败会累计进failedSessionErrorsresultsuccess、success_count、fail_count、failed_sessions、session_output_paths、raw_session_output_paths、raw_export_manifests、elapsed_ms最终结算事件携带成功/失败统计与每个会话的原始导出清单其中raw_export_manifests是「原始导出清单」结构weliveBridge.ts每个会话包含path、rows、bytes以及各类媒体失败计数images_failed/voices_failed/videos_failed/emojis_failed/files_failed可供界面展示导出质量。成功判定与取消进程结束时的成功判定weliveBridge.ts为严格的三条件退出码为0最后一条事件为result在close阶段先drainStdout()排空尾部数据再判定避免分块导出时尾部事件未消费造成误判result.success ! false。任一条件不满足即视为失败并产生诊断信息exit码、exe、platform、arch、pid、最后事件与最近 8 条事件轨迹eventTrail供界面定位问题。取消机制runWeliveExport接受AbortSignalweliveBridge.ts。收到 abort 后先child.kill()若 2 秒内子进程未退出Windows 上执行taskkill /pid pid /T /F连进程树强杀其他平台发送SIGKILL。因此引擎实现应当监听终止信号并尽快退出避免被强制终止导致导出不完整。取消后返回stopped: true失败原因标记为「用户已取消」。另外非 Windows 平台拉起前会先chmodSync(exe, 0o755)确保可执行位weliveBridge.ts若welivePath未配置或文件不存在则直接返回「未配置 WeLive 导出引擎请在设置中指定可执行文件路径」所有会话记为失败。四、在设置界面配置组件路径三类组件的路径均在「设置 - 数据库 - 第三方组件路径」中配置对应 SettingsPage.tsx 中的三个输入框配置项分别写入wcdbLibPath→ WCDB 动态库路径imageNativeAddonPath→ 媒体解密 Node 插件路径welivePath→ WeLive 批量导出引擎可执行文件路径。配置存储的键名定义在 src/services/config.tsWCDB_LIB_PATH、IMAGE_NATIVE_ADDON_PATH、WELIVE_PATH。填写后即时保存并在后续会话/导出操作中按前述协议被加载使用。结语WeFlow 通过「路径配置 严格协议」的方式将 WCDB 数据库读取、DAT 媒体解密、WeLive 批量导出等能力完全外包给用户自选的第三方实现换来的是应用本体与闭源解密逻辑的彻底解耦。对组件实现者而言本文给出的函数签名、接口定义与 NDJSON 协议就是全部契约以wcdb_open_account为必选入口的 C ABI 动态库、以decryptDatNative为核心的 Node 原生插件、以weflow-export子命令 stdin/stdout 交互的批量导出引擎。实现过程中如需确认 JSON 载荷的精确字段请以 electron/services/wcdbCore.ts、electron/services/nativeImageDecrypt.ts 与 electron/services/weliveBridge.ts 中的调用点解析逻辑为最终依据。赞分享【免费下载链接】WeFlowWeFlow - 一个本地的微信聊天记录导出和年度报告应用项目地址https://gitcode.com/gh_mirrors/wefl/WeFlow点击查看免费下载相关推荐深入理解 Humanizer 的 ITruncator 接口可插拔的字符串截断引擎深入理解 Humanizer 的 ITruncator 接口可插拔的字符串截断引擎 本篇文章以 Humanizer 的 ITruncator 接口为核心系统开发工具Zeek 协议分析器脚本接口全索引Analyzer::Tag、插件组件与事件函数详解Zeek 协议分析器脚本接口全索引Analyzer::Tag、插件组件与事件函数详解 本篇技术指南以 Zeek 官方自动生成的协议分析器索引 autogen网络安全网络IDSJetBrains IDEA 接入 AI 编程完全指南终端 AI、第三方插件与 ACP 协议三种方案详解JetBrains IDEA 接入 AI 编程完全指南终端 AI、第三方插件与 ACP 协议三种方案详解 尽管 Cursor、Claude Code、Code文档教程知识库人工智能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表