VC++集成SQLite实战:从源码编译到高性能本地存储
简介本资源面向在Visual C环境下进行桌面开发的程序员聚焦SQLite嵌入式数据库的集成与实战应用帮助解决VC项目中数据库连接、大批量数据快速插入以及查询结果在ListCtrl控件中展示等常见问题。压缩包共61个文件约32.07MB包含sqlite3.h、sqlite3.lib、sqlite3.dll等核心库文件以及cpp、h源码、vcxproj工程文件、sln解决方案、rc资源脚本和多个db示例数据库另附exe、pdb、obj等编译产物便于直接运行与调试。已有527人学习下载。读者可获取一套可直接编译运行的完整VC工程掌握sqlite3_open建立连接、sqlite3_exec批量执行INSERT提升插入效率、sqlite3_prepare_v2配合sqlite3_step遍历结果集并填充ListCtrl的完整实现思路同时了解数据库关闭与错误处理规范适合需要为MFC应用添加本地数据存储与界面展示能力的开发者参考。1. 为什么在 VC 里用 SQLite一个被低估的本地存储方案如果你正在用 Visual C 维护一套桌面工具、工控上位机或者实验室数据采集软件大概率遇到过这种需求程序要存配置、存历史记录、存中间结果但又不值得为它单独装一个 MySQL 或者 SQL Server。早年常见的做法是写 INI、CSV甚至直接二进制 dump结果就是查询靠遍历、并发靠加锁、字段一改全盘崩。SQLite 在 VC 里的价值就在这——一个几百 KB 的 C 库零配置、单文件、支持完整 SQL编译进 exe 就能跑不需要用户装任何东西。它适合谁适合做单机工具、嵌入式上位机、离线数据分析、原型验证的 C 开发者。不适合高并发写入、多进程同时写同一文件的场景这个边界后面会细说。关键词 VC 和 SQLite 的组合核心要解决的就是三件事把 sqlite3.c 编进工程、用 C API 正确打开和操作数据库、在 Windows 下处理好编码和路径这两个老生常谈的坑。下面按我实际拆包复现的顺序讲。2. 把 SQLite 源码编进 VC 工程三种集成方式与选型2.1 为什么优先选源码集成而不是 DLL拿到 SQLite 后第一件事是决定怎么把它接进 VC 工程。常见做法有三种下载预编译的 sqlite3.dll 加导入库、用 vcpkg 之类的包管理器装、直接把 sqlite3.c 和 sqlite3.h 两个文件拖进工程编译。我一般推荐第三种原因很实际VC 工程一旦依赖外部 DLL部署时就要么把 DLL 放同目录要么写 manifest客户机器上少一个文件程序就起不来。而 sqlite3.c 是官方提供的 amalgamation合并版一个 C 文件加一个头文件就是全部编进 exe 后没有任何运行时依赖这对单机工具来说是省心的。代价是编译时间会变长sqlite3.c 大概几万行首次全量编译会明显拖慢。解决办法是把它单独建一个静态库工程只编一次主工程链接这个 lib。下面是我常用的目录结构project/ third_party/ sqlite/ sqlite3.c sqlite3.h src/ main.cpp db_helper.cpp2.2 静态库工程的编译参数在 VC 里新建一个「静态库」工程把 sqlite3.c 加进去然后重点改这几个编译选项。这些参数直接决定后面会不会出现玄学崩溃。配置项推荐值原因预处理器定义SQLITE_ENABLE_COLUMN_METADATA需要拿到列名时用预处理器定义SQLITE_THREADSAFE1多线程访问必须开默认就是 1预处理器定义SQLITE_OMIT_LOAD_EXTENSION不需要动态加载扩展就关掉减小体积运行库与主工程一致MD 或 MT不一致会导致链接期符号冲突C 语言标准编译为 C.c 文件不要强制按 C 编否则可能报错运行库这一项是血泪经验。主工程用 /MD多线程 DLL 版运行库静态库却用 /MT链接时会报一堆_ITERATOR_DEBUG_LEVEL不匹配或者RuntimeLibrary冲突。要么统一要么在项目属性里把「代码生成 → 运行库」逐配置对齐。2.3 主工程链接与头文件引入静态库编好后主工程要做两件事把 sqlite3.h 所在目录加进「附加包含目录」把生成的 .lib 加进「附加依赖项」。如果不想配路径也可以直接把 sqlite3.c 拖进主工程一起编省掉链接步骤代价就是每次改主工程都要重编它。// db_helper.h #pragma once #include sqlite3.h #include string class DbHelper { public: DbHelper(); ~DbHelper(); bool Open(const std::string utf8Path); // 路径统一用 UTF-8 传入 bool Execute(const std::string sql); void Close(); private: sqlite3* db_ nullptr; };这里头文件只暴露 sqlite3.h不暴露任何实现细节。注意Open的参数我特意写成 UTF-8 路径原因在下一章展开——Windows 下中文路径是 VC 用 SQLite 最容易翻车的地方。参数说明db_用裸指针持有连接句柄析构里负责关闭避免忘记释放导致文件被占用。3. 打开、建表、增删改查C API 的正确调用姿势3.1 sqlite3_open_v2 与路径编码处理SQLite 的 C API 里打开数据库用sqlite3_open_v2它比老的sqlite3_open多了 flags 参数能控制只读、创建、URI 等行为。但它在 Windows 上有个历史遗留问题内部按 UTF-8 处理路径而 VC 工程里字符串常常是 GBK 或者宽字符。直接传中文路径轻则打不开重则建出一个乱码文件名的库。bool DbHelper::Open(const std::string utf8Path) { int flags SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; int rc sqlite3_open_v2(utf8Path.c_str(), db_, flags, nullptr); if (rc ! SQLITE_OK) { // 打开失败时 db_ 可能非空必须 close 防止泄漏 if (db_) { sqlite3_close(db_); db_ nullptr; } return false; } // 开启外键约束默认是关的 sqlite3_exec(db_, PRAGMA foreign_keysON;, nullptr, nullptr, nullptr); return true; }逻辑说明SQLITE_OPEN_FULLMUTEX让连接内部串行化多线程共用一个连接时更安全代价是性能略降。如果确定单线程访问可以换成SQLITE_OPEN_NOMUTEX。参数utf8Path必须是 UTF-8 编码如果你的路径来自 MFC 的 CString 或者 Windows API 的宽字符需要先转换// 宽字符转 UTF-8Windows 下常用做法 std::string WideToUtf8(const std::wstring wstr) { if (wstr.empty()) return {}; int len WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), nullptr, 0, nullptr, nullptr); std::string out(len, 0); WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.size(), out[0], len, nullptr, nullptr); return out; }这个转换函数是 VC 下处理中文路径的标配别用std::string直接塞 GBKSQLite 不认。3.2 用 sqlite3_exec 做建表和简单写入建表、插入这类不需要返回结果集的语句用sqlite3_exec最省事。它接受一条 SQL 字符串和一个回调回调用于处理 SELECT 结果。bool DbHelper::Execute(const std::string sql) { char* errMsg nullptr; int rc sqlite3_exec(db_, sql.c_str(), nullptr, nullptr, errMsg); if (rc ! SQLITE_OK) { // errMsg 由 SQLite 分配必须用 sqlite3_free 释放 if (errMsg) { sqlite3_free(errMsg); } return false; } return true; }调用示例DbHelper db; db.Open(D:/data/app.db); db.Execute(CREATE TABLE IF NOT EXISTS logs( id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT NOT NULL, level INTEGER, msg TEXT);); db.Execute(INSERT INTO logs(ts, level, msg) VALUES(2025-01-01 10:00:00, 2, start););参数说明CREATE TABLE IF NOT EXISTS保证重复执行不报错适合程序启动时初始化。AUTOINCREMENT会额外维护一张 sqlite_sequence 表如果只是要自增主键其实INTEGER PRIMARY KEY本身就自增可以省掉 AUTOINCREMENT 的开销。3.3 预处理语句与参数绑定防注入和提性能拼接 SQL 字符串是新手最容易犯的错一是注入风险二是每次都要重新解析。正确做法是用sqlite3_prepare_v2加sqlite3_bind_*。bool InsertLog(sqlite3* db, const std::string ts, int level, const std::string msg) { const char* sql INSERT INTO logs(ts, level, msg) VALUES(?, ?, ?);; sqlite3_stmt* stmt nullptr; if (sqlite3_prepare_v2(db, sql, -1, stmt, nullptr) ! SQLITE_OK) return false; // 参数索引从 1 开始不是 0 sqlite3_bind_text(stmt, 1, ts.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 2, level); sqlite3_bind_text(stmt, 3, msg.c_str(), -1, SQLITE_TRANSIENT); int rc sqlite3_step(stmt); sqlite3_finalize(stmt); // 无论成功失败都要 finalize return rc SQLITE_DONE; }逻辑说明sqlite3_bind_text的第四个参数是长度传 -1 表示按 null 结尾自动计算第五个参数SQLITE_TRANSIENT告诉 SQLite 复制一份字符串因为ts和msg是临时对象不复制的话 step 时可能已经析构。如果字符串生命周期覆盖整个 step 过程可以用SQLITE_STATIC省一次拷贝。sqlite3_finalize必须调用否则语句对象泄漏长时间运行会耗尽内存。3.4 查询结果集的遍历SELECT 用sqlite3_step循环返回SQLITE_ROW表示还有行SQLITE_DONE表示结束。void QueryLogs(sqlite3* db) { const char* sql SELECT id, ts, level, msg FROM logs WHERE level ?;; sqlite3_stmt* stmt nullptr; sqlite3_prepare_v2(db, sql, -1, stmt, nullptr); sqlite3_bind_int(stmt, 1, 1); while (sqlite3_step(stmt) SQLITE_ROW) { int id sqlite3_column_int(stmt, 0); const unsigned char* ts sqlite3_column_text(stmt, 1); int level sqlite3_column_int(stmt, 2); const unsigned char* msg sqlite3_column_text(stmt, 3); // 注意column_text 返回的指针在下次 step 或 finalize 后失效 std::string tsStr ts ? (const char*)ts : ; std::string msgStr msg ? (const char*)msg : ; } sqlite3_finalize(stmt); }关键点sqlite3_column_text返回的指针指向 SQLite 内部缓冲区下一次sqlite3_step或者sqlite3_finalize之后就可能失效必须立刻拷贝到自己的 std::string 里。这个坑我在排查一个偶发乱码问题时花了半天才定位到。4. 事务、索引与并发让 SQLite 在 VC 里跑得稳4.1 批量写入必须包事务SQLite 默认每条 INSERT 都是一个独立事务每次都要写磁盘、刷日志。批量插一万条不包事务可能要几十秒包了事务通常一秒内完成。这是最容易被忽略的性能开关。bool BatchInsert(sqlite3* db, const std::vectorLogItem items) { sqlite3_exec(db, BEGIN TRANSACTION;, nullptr, nullptr, nullptr); const char* sql INSERT INTO logs(ts, level, msg) VALUES(?, ?, ?);; sqlite3_stmt* stmt nullptr; sqlite3_prepare_v2(db, sql, -1, stmt, nullptr); for (const auto it : items) { sqlite3_bind_text(stmt, 1, it.ts.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 2, it.level); sqlite3_bind_text(stmt, 3, it.msg.c_str(), -1, SQLITE_TRANSIENT); if (sqlite3_step(stmt) ! SQLITE_DONE) { sqlite3_exec(db, ROLLBACK;, nullptr, nullptr, nullptr); sqlite3_finalize(stmt); return false; } sqlite3_reset(stmt); // 重置语句以便复用比重新 prepare 快 } sqlite3_finalize(stmt); sqlite3_exec(db, COMMIT;, nullptr, nullptr, nullptr); return true; }参数说明sqlite3_reset把语句恢复到 prepare 后的状态绑定值需要重新 bind但省掉了重新解析 SQL 的开销。出错时 ROLLBACK 保证要么全成功要么全失败避免写一半留下脏数据。4.2 索引的取舍查询慢的时候第一反应是加索引但索引不是越多越好。每个索引都会拖慢写入因为插入时要同步更新 B 树。我一般只给 WHERE 条件里高频出现、且区分度高的列建索引。CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level); CREATE INDEX IF NOT EXISTS idx_logs_ts ON logs(ts);如果一张表只有几百行加索引反而可能让查询变慢因为优化器可能选错执行计划。判断标准用EXPLAIN QUERY PLAN看是否走了索引。EXPLAIN QUERY PLAN SELECT * FROM logs WHERE level 2;输出里出现USING INDEX idx_logs_level说明命中出现SCAN TABLE说明全表扫描。4.3 WAL 模式与多线程访问边界SQLite 默认的日志模式是 DELETE写的时候会锁整个库。开启 WALWrite-Ahead Logging后读和写可以并发适合「一个写线程 多个读线程」的桌面程序。sqlite3_exec(db_, PRAGMA journal_modeWAL;, nullptr, nullptr, nullptr); sqlite3_exec(db_, PRAGMA synchronousNORMAL;, nullptr, nullptr, nullptr);参数说明synchronousNORMAL在 WAL 模式下是安全的比 FULL 快很多只在系统崩溃时可能丢最后几条事务对日志类数据可以接受。注意 WAL 会额外生成-wal和-shm两个文件程序退出时要确保连接正常关闭否则这两个文件会残留。边界要说清楚WAL 解决的是同一进程内多线程读写不是多进程。两个 exe 同时写同一个库文件SQLite 靠文件锁保证一致性但写冲突时会返回SQLITE_BUSY需要自己重试。我一般会设一个 busy timeoutsqlite3_busy_timeout(db_, 3000); // 遇到锁时最多等 3 秒这样短时间的锁竞争能自动等待不用在代码里写重试循环。5. 避坑与排查VC 下 SQLite 最常见的五个翻车点5.1 中文路径打不开或建出乱码文件现象sqlite3_open_v2返回非 OK或者数据库文件建出来了但文件名是乱码程序找不到。原因VC 工程默认字符集可能是 Unicode 或多字节传给 SQLite 的路径编码不是 UTF-8。SQLite 在 Windows 上按 UTF-8 解释路径GBK 字节流会被错误解析。解决所有路径在传入前统一转成 UTF-8用上面WideToUtf8那类函数。如果工程是多字节字符集先确认源文件编码再决定是否需要先转宽字符再转 UTF-8。5.2 忘记 finalize 导致内存持续增长现象程序跑几小时后内存占用越来越高最后卡死。原因sqlite3_prepare_v2创建的 stmt 没有sqlite3_finalize每次查询泄漏一点。解决把 stmt 的生命周期用 RAII 包起来或者严格保证每条路径都 finalize。我习惯写一个小的 guard 类析构时自动 finalize避免漏掉。5.3 运行库不匹配导致链接错误现象链接时报LNK2038或_ITERATOR_DEBUG_LEVEL不匹配。原因静态库和主工程的运行库配置/MD vs /MTDebug vs Release不一致。解决逐配置检查「代码生成 → 运行库」确保 sqlite 静态库和主工程完全一致。Debug 配 DebugRelease 配 Release不要混用。5.4 SQLITE_BUSY 频繁出现现象多线程写入时sqlite3_step返回SQLITE_BUSY数据没写进去。原因默认没有 busy timeout遇到锁立即失败或者多个连接同时写。解决设置sqlite3_busy_timeout并把写操作集中到一个线程其他线程通过队列把写请求发过去。读操作可以多线程并发WAL 模式下读不阻塞写。5.5 事务没提交导致数据丢失现象程序正常退出但最后一批数据没进库。原因BEGIN之后没有COMMIT或者中途 return 跳过了提交。解决把事务封装成 RAII 对象析构时如果没提交就自动 ROLLBACK强制自己在逻辑结束时显式提交。这个习惯能避免大部分「数据莫名丢失」的问题。6. 进阶技巧用 sqlite3_exec 回调做通用查询封装前面用的都是 prepare/step 那套写多了会发现每个查询都要重复绑定和取值。如果只是做工具类程序不追求极致性能可以用sqlite3_exec的回调做一个通用查询函数把结果直接塞进vectormapstring,string代码量能少一半。// 通用查询返回每行一个 map列名到值的映射 static int QueryCallback(void* data, int argc, char** argv, char** colNames) { auto* rows static_caststd::vectorstd::mapstd::string, std::string*(data); std::mapstd::string, std::string row; for (int i 0; i argc; i) { // argv[i] 为 nullptr 表示该列为 NULL row[colNames[i]] argv[i] ? argv[i] : ; } rows-push_back(std::move(row)); return 0; // 返回非 0 会中止查询 } std::vectorstd::mapstd::string, std::string Query(sqlite3* db, const std::string sql) { std::vectorstd::mapstd::string, std::string rows; char* errMsg nullptr; int rc sqlite3_exec(db, sql.c_str(), QueryCallback, rows, errMsg); if (rc ! SQLITE_OK errMsg) { sqlite3_free(errMsg); } return rows; }逻辑说明回调的argc是列数argv是值数组colNames是列名数组。返回 0 继续返回非 0 会中断查询。这个封装适合配置读取、报表导出这类场景缺点是所有值都按字符串处理类型信息丢失NULL 和空字符串无法区分。如果业务对类型敏感还是老老实实用 prepare/step。参数上有个细节sqlite3_exec的回调里不要做耗时操作也不要再调用同一个连接的 SQLite API否则可能死锁。我一般只在回调里做数据搬运复杂处理放到外面。验证封装是否正确最简单的办法是拿一个已知表跑一遍对比SELECT count(*)和返回的 vector 大小。另外注意sqlite3_exec遇到多条 SQL 用分号隔开时会依次执行回调会对每条 SELECT 都触发别把 INSERT 和 SELECT 混在一条 exec 里。从那以后我每次把 SQLite 接进新工程都会先跑一遍中文路径建库、批量插入一万条计时、多线程读写压测这三步确认没问题再往下写业务。这套流程帮我省掉了不少返工。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Avalonia桌面开发:整合SukiUI与LiveChart2并修复字体显示问题

Avalonia桌面开发:整合SukiUI与LiveChart2并修复字体显示问题

简介:这是一份基于 Avalonia 的跨平台桌面程序源码包,面向希望快速上手 XAML 界面开发与多系统部署的 .NET 开发者;项目聚焦 Linux 环境,整合 LiveChart2 与 SukiUI,并在 Ubuntu 20.04 上完成验证,同时解决…

2026/10/13 19:23:23 阅读更多 →
手机锁屏密码忘了?官方解锁全攻略,数据能否保住看这里

手机锁屏密码忘了?官方解锁全攻略,数据能否保住看这里

简介:本资源是一份聚焦华为手机解锁操作的图文教程文档,适合需要刷机、Root 或对系统进行深度定制的华为手机用户阅读。内容首先交代解锁的必要性与潜在风险,强调操作前备份数据、正确安装驱动的重要性;随后按步骤讲解了准备工作、…

2026/10/12 15:21:27 阅读更多 →
技术月结复盘:架构、云成本、性能优化与踩坑实录

技术月结复盘:架构、云成本、性能优化与踩坑实录

做月结栏目,我这儿说的可不是写日记,是每个月底把当月的动态、架构、云技术、算法、后端、前端、收听/收看、英文、书籍、影视、好歌、新奇全部盘一遍,加上定期更新的承诺,压缩成一篇能反复回看的东西。这是我这个栏目的第二回合。…

2026/10/13 20:06:11 阅读更多 →

最新新闻

DeepSeek写教案怎么导出Word?完整步骤

DeepSeek写教案怎么导出Word?完整步骤

DeepSeek写教案怎么导出Word?完整步骤用 DeepSeek 写教案,最省事的做法是让它直接按 Markdown 输出,再整篇导出成 Word。教案里常见的教学目标、课时安排、板书设计、作业布置,在 Markdown 里就是标题层级和列表;一旦用…

2026/10/14 2:13:20 阅读更多 →
MateChat Layout 布局组件:用 5 个语义容器搭建聊天界面骨架与自动滚动机制

MateChat Layout 布局组件:用 5 个语义容器搭建聊天界面骨架与自动滚动机制

前端UI组件AI 应用 【免费下载链接】MateChat 前端智能化场景解决方案UI库,轻松构建你的AI应用,我们将持续完善更新,欢迎你的使用与建议。 官网地址:https://matechat.gitcode.com 项目地址: https://gitcode.com/DevC…

2026/10/14 2:13:20 阅读更多 →
coreboot 开源固件与 Coverity Scan 静态分析集成实践指南

coreboot 开源固件与 Coverity Scan 静态分析集成实践指南

固件嵌入式操作系统驱动开发 【免费下载链接】coreboot Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We dont handle Pull Requests. 项目地址: https://gitcode.com/gh_mirrors/co/coreboot 点击查看 免费下载 导读 本文…

2026/10/14 2:13:20 阅读更多 →
Go 语言通过 WQL 查询 Windows WMI:wmi 包使用指南与源码解析

Go 语言通过 WQL 查询 Windows WMI:wmi 包使用指南与源码解析

后端云原生运维虚拟化人工智能AI 应用 【免费下载链接】cloudpods 开源、云原生的多云管理及混合云融合平台 项目地址: https://gitcode.com/yunionio/cloudpods 点击查看 免费下载 wmi 是 Stack Exchange 开源的 Go 包,它为开发者提供了一套基于 WQL&a…

2026/10/14 2:13:20 阅读更多 →
TorchAir 图模式构图元素 Clone 接口详解:基于 TensorMove 的单 Tensor 拷贝与依赖控制

TorchAir 图模式构图元素 Clone 接口详解:基于 TensorMove 的单 Tensor 拷贝与依赖控制

人工智能模型编译Ascend 【免费下载链接】torchair TorchAir 支持用户基于PyTorch框架和torch_npu插件在昇腾NPU上使用图模式进行推理。 项目地址: https://gitcode.com/Ascend/torchair 点击查看 免费下载 导读 本文面向使用 TorchAir 在昇腾 NPU 上开展图模式推…

2026/10/14 2:13:20 阅读更多 →
三星预计实现创纪录的800亿美元利润

三星预计实现创纪录的800亿美元利润

三星电子公司表示,预计将在本季度创造科技行业历史上前所未有的季度利润纪录,首次突破100万亿韩元大关。在今日晚间发布的第三季度初步财报中,该公司透露预计营业利润将达到惊人的107.4万亿韩元(约合801.7亿美元)&…

2026/10/14 2:12:20 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →