尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
解析Windows打印后台SPOOL文件:从打印服务器还原每一次打印底账
简介针对打印任务信息获取这份工具包提供了解析SPOOL文件SHD/SPL的完整方案适用于需要旁路监控打印行为的开发及运维人员。与Hook打印函数、注册消息等侵入式手段不同直接从系统生成的SHD与SPL文件中提取任务元数据和压缩图像数据信息更全面实施也更轻量适合用于打印审计、用量统计或故障排查等场景。包内共55个文件包含C工程源码、编译好的exe工具、SHD/SPL测试样本、说明文档以及“将SPL剥离成EMF”的技术博客存档压缩包整体约19.93MB目录层级简洁便于按需检索。已有1969人学习下载。示例工程展示了从SPL中剥离EMF文件的解析方法配合splview.exe可直观查看解析结果帮助读者快速掌握SPOOL内部结构进而自定义扩展监控功能。1. 打印信息获取从 SPOOL 文件里翻出每一次打印的底账很多网管都遇到过这种尴尬有人把公司内部资料打印走了打印机自带面板只显示“已打印 47 页”系统日志里只剩一个 Job 编号文档名叫什么、哪个账号发的、几点发的全是黑匣子。我处理这类打印监控需求时最顺手也最可靠的办法就是直接去解析 Windows 打印后台 Spooler 落盘的 SPOOL 文件。这套方法绕过厂商接口不依赖打印机管理平台只要你能拿到 FileServer 或打印服务器上C:\Windows\System32\spool\PRINTERS目录里的 .shd 和 .spl 文件就能把文档名、用户名、页数、份数、纸张方向、时间戳逐项抠出来。适合做打印审计、耗材成本核算、涉密追溯的从业者也适合想搞懂 Windows 后台打印机制的开发人员。2. 认清弹药库SPOOL 文件的结构与选型依据2.1 现场地形PRINTERS 目录下的三种成分Windows 的后台打印服务Spooler接到打印任务后会在PRINTERS目录下生成三种类型文件。第一步先要把它们认全否则后续解析时经常会拿错对象。文件类型扩展名角色生命周期任务控制文件.shd记录任务概要文档名、账号、端口、优先级、大小任务进入队列时创建任务完成删除页面数据文件.spl保存交给打印驱动的实际绘图指令同上部分 RAW 任务完成后立即删临时文件.tmpSpooler 写数据时的中间缓冲崩溃或断电后常残留可忽略三类文件共用同一个数字前缀比如00012.shd和00012.spl数字就是后台打印任务的 Job ID。文件名后半段往往会带端口名例如00012_FRP403_1.spl这种能省去查端口映射的功夫。注意.shd是纯二进制结构体可以用 Python 的struct直接拆.spl的结构则由打印驱动决定常见的 EMF 和 RAW 两种格式差异极大下面详细说。2.2 为什么非读不可的往往是 .spl 而不是 .shd.shd文件体积通常在 1KB 到 4KB 之间存的只是任务的“封面信息”——谁发的、发到哪、任务名是什么。.spl才是“正文”里面的数据量动辄几百 KB 到几十 MB页面数量、每页的绘图指令、文字内容都藏在其中。从打印监控角度我一般把.shd当“目录”把.spl当“账本”。数页数是打印审计中最核心的指标如果只看.shd多数版本的 SHD 头里确实有Pages字段但存在两个坑一是某些驱动在上送任务时页数字段填的是 0由 EMF 回放时才真正确定二是打印异常中断时 SHD 里的页数停留在发送中状态误差很大。因此页数必须从.spl里读如果内容是 EMF绝大多数驱动默认可以按 EMF 记录边界精确回放页数如果内容是 RAWPostScript 或 PCL 转义流则只能统计数据块大小或匹配换页指令可靠性低一档。2.3 采集时机决定成败Spooler 删文件比你想象中快解析技术上不难难的是把文件抓到手里。默认情况下Spooler 在打印任务渲染完成后会在几秒内释放并删除对应的 .shd/.spl。如果监控脚本按固定间隔去扫目录经常只看到一堆还没来得及处理的 .tmp 文件。我常用的三种前置处理手段按稳妥程度排序在打印服务器上把 Spooler 的“保留失败任务”策略打开但这样只对失败任务有效。修改注册表让 Spooler 在打印完成后保留 SPL 文件代价是磁盘占用增长适合临时取证。用卷影复制VSS或文件系统过滤驱动直接抓取快照这种方法对线上打印无干扰是长期监控的首选。后面第 3 章会给出一个完整的解析流程第 4 章专门讲这些窗口期和权限相关的坑。3. 完整分析流程从目录快照到页数回放的三个步骤3.1 第一步用 Robocopy 做只读快照别手点复制粘贴直接在资源管理器里复制 PRINTERS 目录你会复制到一半文件缺失或目录锁死的报错。因为 Spooler 持有文件句柄普通用户复制时会碰到文件正在被占用。正确的做法是用 Robocopy 以备份模式拉取快照相当于把被占用的文件也抓下来。robocopy \\PrintServer\C$\Windows\System32\spool\PRINTERS D:\spool_snapshot /MIR /B /R:1 /W:1 /XJ逻辑说明/MIR镜像整个目录确保首次抓取后每次增量只拉新文件/B走备份模式读取不需要逐个文件分配读写权限能绕过部分文件占用锁/R:1 /W:1把重试次数和等待时间降到最低避免在某个坏文件上卡死/XJ排除目录联接点防止递归到错误位置。参数说明如果目标打印服务器不在域内/B模式要求执行账号有“备份文件和目录”权限普通域账号默认就有若是本机分析则直接用管理员身份运行。抓取时间建议选业务低峰因为PRINTERS里的文件本身就是待打印任务的实时快照业务高峰时文件正在疯狂写入镜像出来的后半段文件可能旧、前半段文件可能新统计口径会乱。3.2 第二步剖析 .shd 头结构把文档名和账号抠出来.shd文件不是一个扁平结构而是由若干固定版本的结构体组成。解析时不要迷信固定偏移要按头部的版本号字段分流。下面这段 Python 代码能解析最常见的 Windows 10 和 Server 2016 的 SHD 格式拿到任务 ID、文档名、用户名、端口名。import struct from pathlib import Path def parse_shd(file_path): with open(file_path, rb) as f: data f.read(4096) # SHD 头足够小读前 4KB # 前 16 字节版本头。常见魔数 0x00000001 表示旧版结构 # 不同系统版本该字段不同解析前先判断 version struct.unpack_from(I, data, 0)[0] if version ! 1: # 高版本 Windows 的 SHJOB 头从偏移 0 处也是版本号 version struct.unpack_from(I, data, 12)[0] # 多数版本结构JobId(4) 后面是定长 Unicode 字符串 job_id struct.unpack_from(I, data, 4)[0] # 文档名和用户名在不同版本中偏移不同。 # 常见做法先扫整个 data按 UTF-16LE 解码后找两个连续字符串 text data.decode(utf-16-le, errorsignore) parts [p for p in text.split(\x00) if p.strip()] doc_name parts[0] if len(parts) 0 else user_name parts[1] if len(parts) 1 else return { job_id: job_id, doc_name: doc_name, user_name: user_name, device_name: parts[2] if len(parts) 2 else } if __name__ __main__: p Path(D:/spool_snapshot/00012.shd) print(parse_shd(p))逻辑说明SHD 结构体的核心是将定长二进制头和后续的 Unicode 字符串块相连struct.unpack_from负责跳过数字头字符串段则用utf-16-le解码后按\x00切分。打印服务器上中文账号名和中文文档名很常见所以解码时必须显式用 UTF-16LE。参数说明version字段在不同系统版本上位置和含义都有差异代码里做了两次尝试。如果你手头全是 Windows Server 2019可以只解析偏移 12 的版本号但碰到混杂环境还是按“版本号分流”的思路做否则会翻车。返回的字段中device_name端口名对得上打印机实物后期审计报表需要它来归属打印机设备。3.3 第三步从 .spl 里精确统计页数EMF 记录边界法拿到.spl之后先判断是 EMF 还是 RAW。EMF 文件的特征是开头是\x01\x00\x00\x00这样的四字节记录类型EMR_HEADER值 1RAW 文件是%!PSPostScript或\x1B%PCL 转义开头。对 EMF 类型的 SPL 文件我一般直接用“读 EMF 记录边界”的方式数页import struct EMR_HEADER 1 EMR_EOF 14 # EMR_EOF 记录表示一个页面/绘图段的结束 def count_pages_from_spl(spl_path): page_count 0 offset 0 with open(spl_path, rb) as f: data f.read() while offset 8 len(data): # 每一条 EMF 记录类型(4字节) 长度(4字节) rec_type, rec_len struct.unpack_from(II, data, offset) if rec_len 8 or offset rec_len len(data): break if rec_type EMR_HEADER: # 新 EMF 流开始页数加 1同一 SPL 内可能打包多个 EMF page_count 1 if rec_type EMR_EOF: # 页绘制结束同一 EMF 内可能有多段 EOF # 我们只数 EMR_HEADER避免把单页多段描绘重复计页 pass offset rec_len return max(page_count, 1) # 至少一页 if __name__ __main__: print(count_pages_from_spl(D:/spool_snapshot/00012.spl))逻辑说明EMF 记录是“类型 长度”的 TLV 结构遍历时按长度跳转即可。新页面开始时驱动会写入一个新的EMR_HEADER记录页面绘制完成后写EMR_EOF。数EMR_HEADER比数EMR_EOF更稳因为有些驱动在一个页面范围内会写多段EMF_EOF表示图层结束但不会重复写EMR_HEADER。参数说明rec_len小于 8 或超出文件尾部说明数据被 Spooler 截断此时直接break页面数以已解析部分为准。对 RAW 类型的 SPL上面的代码不适用常见做法是扫描\x0c换页符统计页数但 PostScript 的showpage和 PCL 的\x0c混用时这个统计误差很大建议对 RAW 文件只做“字节数统计”不要硬做精确页数否则打印审计数据对不上账会很被动。4. 避坑指南解析 SPOOL 文件时最容易翻车的五个场景4.1 文件还没抓完Spooler 就把任务删了现象快照目录里全是.tmp.shd和.spl数量寥寥监控报表显示“全天只有 3 个打印任务”与打印服务器的实际任务数严重不符。原因打印任务完成之后Spooler 默认立即删除对应的 .shd/.spl。Robocopy 镜像速度再快也快不过 Spooler 的清理线程。特别在打印机直通和 RAW 打印模式下数据文件几乎一闪而过。解决临时取证场景在打印服务器上运行以下命令修改注册表让 Spooler 保留已完成任务的 SPL 文件然后重启 Spooler 服务。Set-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Print\Spooler -Name PreserveJob -Value 1 Restart-Service Spooler说明PreserveJob置 1 后SPL 文件会保留到新任务覆盖适合做审计实验。长期监控建议改成每 5 分钟用 VSS 写一次快照这样不会影响生产环境。用完记得把注册表改回 0 并重启 Spooler否则磁盘会被残留 SPL 撑爆。4.2 SHD 结构体按固定偏移解析字段全错位现象解析出来的用户名是乱码文档名是打印机端口名Job ID 是个巨大数字每条记录都对不上。原因SHD 结构体在 Windows Server 2003、2008、2012、2016 及 Win10 之间改了至少三个版本。旧版SHJOB结构里DocumentName是定长 64 字节的char[]新版则是WCHAR[]变长字段。按旧版偏移硬解析新版文件必然错位。解决解析前先读前 4 字节版本号再按版本分支处理。代码里给出的是兼容写法实际我开发时会为每个版本写一个解析类。建议你在做这个功能时直接收集三类版本文件各 20 个做一次回归样本比啥文档都好使。4.3 把 PCL 的字体下载指令当成换页符页数统计虚高现象同一份 5 页 Word 文档从 RAW SPL 统计出的页数是 23 页和真实页数差了近 4 倍。原因PCL 流里的\x0c换页符出现在字体下载、宏定义、介质选择等多种控制序列里根本不是真正的物理分页。直接扫描换页符统计 RAW 页数属于拿“内容字节特征”当“逻辑语义”统计值只能当估算。解决对 RAW 文件停止“精确数页”改为统计数据量KB和首次/末次时间。如果必须精确页数就改打印机驱动配置强制输出 EMF 而不是 RAW。具体操作控制面板 → 打印机属性 → 高级 → 选中“启用高级打印功能”通常驱动就会走 EMF 路线。4.4 中文文档名导出 CSV 后全是乱码和断行现象解析结果在控制台打印正常导出 CSV 用 Office 打开后中文显示乱码文档名字段被截断到一半。原因代码用 UTF-8 写 CSV但 Windows 版 Office 默认按 ANSI 读取同时 SHD 中定长字符串可能包含尾部填充的中断字符\x00字符串在填充处被截断。解决写 CSV 时加上 UTF-8 BOM并把字符串统一做\x00清理。import csv with open(output.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([JobID, DocName, UserName, Pages]) for rec in records: writer.writerow([ rec[job_id], rec[doc_name].split(\x00)[0].strip(), rec[user_name].split(\x00)[0].strip(), rec[pages] ])说明utf-8-sig是 Python 内置的带 BOM 编码器Excel 打开时自动识别\x00只在解码后还残留时出现做一次切分清理是防御性编程成本极低。另注意 SHD 里的定长字段有时会带尾部空格别忘了.strip()。4.5 抓取 PRINTERS 目录时权限不足Robocopy 直接报错退出现象robocopy镜像是 0 个文件复制成功错误代码 5提示“拒绝访问”。原因C:\Windows\System32\spool\PRINTERS目录默认只有 SYSTEM 和管理员组才能列目录普通域用户可以发起打印任务但没有权限读该目录。解决不要直接给用户账号单独加 NTFS 权限那样会在审计时留下 ACL 变更记录容易被安全团队盯上。推荐以下两种方式# 方式一临时以 SYSTEM 身份运行镜像命令需 PsTools psexec -s robocopy C:\Windows\System32\spool\PRINTERS D:\spool_snapshot /MIR /B # 方式二在服务中使用 Service Account 赋予“备份文件和目录”权限 # 然后在任务计划程序里用该账号执行 robocopy说明方式一适合一次性取证方式二适合长期监控。psexec -s不是去提升当前用户权限而是让进程完全以 SYSTEM 身份运行同时不影响目标目录的 ACL 结构。注意psexec命令在杀软环境中容易被拦截配置杀软白名单后再用。5. 把解析流程工程化做成能日常跑的打印监控工具5.1 封装 CLI 工具一次扫描输出结构化报表手动跑脚本只能处理单个文件实际监控场景要批量扫描整个快照目录。我用argparse写一个命令行入口支持--directory指定快照目录、--format切换 CSV 或 JSON 输出。import argparse import json import csv from pathlib import Path from .parse_shd import parse_shd from .parse_spl import count_pages_from_spl def process_directory(spool_dir, fmtcsv, raw_threshold50): records [] for shd_file in sorted(Path(spool_dir).glob(*.shd)): try: meta parse_shd(shd_file) spl_file shd_file.with_suffix(.spl) pages count_pages_from_spl(spl_file) if spl_file.exists() else 0 records.append({**meta, pages: pages, src_file: shd_file.name}) except Exception as e: records.append({error: str(e), src_file: shd_file.name}) return records if __name__ __main__: ap argparse.ArgumentParser(descriptionPrint job parser) ap.add_argument(--directory, requiredTrue, helpsnapshot dir) ap.add_argument(--format, choices[csv, json], defaultcsv) args ap.parse_args() recs process_directory(args.directory) if args.format json: print(json.dumps(recs, ensure_asciiFalse, indent2)) else: w csv.DictWriter(open(print_jobs.csv, w, newline, encodingutf-8-sig), fieldnames[job_id, doc_name, user_name, pages, src_file]) w.writeheader() w.writerows(recs)逻辑说明glob(*.shd)拿到全部任务控制文件后再按文件名替换后缀找同名.spl.shd能解析但.spl缺失时页数补 0并把src_file属性保留给排查人员。异常捕获放在单条记录粒度某条坏数据不会中断整个扫描。参数说明raw_threshold参数RAW 类型数据量阈值在代码里保留了接口但实际开发时我一般不放它进外层 CLI因为 RAW 本身就退化为字节级统计给用户一个模糊参数反而容易让人误解“可以精确统计 RAW 页数”。CLI 最好只有--directory和--format两个参数保持简单。5.2 把结果导入 SQLite做按用户聚合的打印报表CLI 输出 CSV 只是为了快速查看真正的审计需要按部门、按时间段、按打印机聚合。我一般会把结果导入 SQLite然后用一句 GROUP BY 产生汇总表。-- 每月每个用户的打印总量和总页数 SELECT strftime(%Y-%m, print_time) AS month, user_name, COUNT(*) AS job_count, SUM(pages) AS total_pages FROM print_jobs GROUP BY month, user_name ORDER BY total_pages DESC;逻辑说明如果直接拿 CSV 做聚合需要在 Excel 里做透视表数据量大了卡顿SQLite 单文件、零配置非常适合这种几十万行的审计数据。print_time字段在真实部署时我会从快照文件的修改时间推算不需要依赖 SHD 里可能缺失的时间字段。表结构设计至少包含job_id、doc_name、user_name、pages、device_name、scan_time六列。scan_time是快照生成时间job_id作为去重键因为同一次抓取可能因为这批文件被 Spooler 清理而只能看到部分下次抓取又会补齐重复导入会虚增任务数。5.3 实时监控扩展用目录事件代替定时任务如果不想依赖 Robocopy 定时快照还有一种更实时但更脆的方案直接用文件系统监听PRINTERS目录当新的.spl文件出现时立刻触发解析。前端用 Python 的watchdog库就够了。from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class SpoolHandler(FileSystemEventHandler): def on_created(self, event): if event.src_path.endswith(.spl): shd_path event.src_path[:-4] .shd if os.path.exists(shd_path): # 延迟 2 秒解析等待 SHD 完整写入 time.sleep(2) meta parse_shd(shd_path) pages count_pages_from_spl(event.src_path) print(f新任务: {meta[user_name]} 打印 {meta[doc_name]} 共 {pages} 页) if __name__ __main__: observer Observer() observer.schedule(SpoolHandler(), rC:\Windows\System32\spool\PRINTERS, recursiveFalse) observer.start()逻辑说明on_created触发时机是文件创建事件此时 Spooler 可能还在写内容。加 2 秒延迟是为了等文件大小稳定实际部署时建议改成“等文件大小连续 3 次不变再解析”避免读到半截数据。参数说明此方案仅适用于解析进程和 Spooler 在同一台机器上运行的情况。如果快照在远程 Server 上则建议改走共享目录监控或直接把快照做成持续同步到本地再本地触发。5.4 与系统日志对账确认解析数据可信度的最后一环工具跑通后不能直接上线先用至少一个工作日的打印记录和“打印服务器的事件日志”对账。具体做法是让同事打印 10 份不同页数的测试文档然后用解析工具导出任务清单再和Microsoft-Windows-PrintService/Operational事件日志里的Event ID 307打印任务完成做逐条比对。对比字段事件日志来源SPOOL 解析来源常见不一致原因任务 IDEvent 307 里 Job IDSHD 文件前缀数字事件日志保留周期短旧的缺失用户名事件日志关联账号SHD 内 UserName 字段快照时间晚于用户注销SHD 已删页数Event 307 的 PagedPrintedEMF 记录数驱动渲染前取消任务导致 EMF 不完整对账能发现两类问题一类是 Spooler 清理太快导致快照缺失你需要在监控策略上把快照周期缩小到 1 分钟以内另一类是 EMF 页数与驱动报告的页数不一致这说明当前打印机驱动不是纯 EMF 模式需要回到第 4.3 节去调整驱动配置。6. 进阶验证技巧造一批可控测试页把解析逻辑钉死在正确轨道上6.1 用纯脚本生成 EMF 测试文件自测解析器不依赖打印机没有打印机也能验证count_pages_from_spl的逻辑方法是用 Python 裸写一个最小 EMF 文件。虽然 EMF 的规范很庞大但我们只需要构造“头部 两条空记录 EOF”的合法骨架让解析器能判别页数。import struct def build_emf_page(page_count): # 简化 EMF 文件每个页一个 EMR_HEADER EMR_EOF data b for _ in range(page_count): # EMR_HEADER 记录类型 1长度 88标准最小头 header struct.pack(II, 1, 88) b\x00 * 80 # EMR_EOF 记录类型 14长度 20 eof struct.pack(II, 14, 20) b\x00 * 12 data header eof return data with open(test_pages.emf, wb) as f: f.write(build_emf_page(5))逻辑说明EMR_HEADER的长度不是固定的 88但解析器只关心类型和长度两个字段构造一个 88 字节的合法记录足以通过遍历。EMR_EOF标准长度是 20 字节同样只保留最简字段。用 5 页的骨架文件喂给解析器输出pages5解析逻辑才算过了第一关。参数说明这只是验证解析器的逻辑正确性不验证“真实驱动程序写出的 EMF 是否符合规范”。所以自测通过后还要走到第 6.2 步用真实打印任务做端到端测试。6.2 端到端验证让某位同事打印测试文档反向核对解析结果端到端测试是最容易暴露版本兼容问题的一步。我在实际项目中会让 A 同学在 Word 里打一份标题为“测试文档-2024秋季”的五页文档PDF 另存后打印然后立刻抓取快照并比对。验证清单文档名是否与 SHD 里解析出的doc_name完全一致含中文。页数是否为 5如果解析出 4 或 6优先怀疑驱动把封面和空白页过滤掉了。用户名是否与 A 同学的登录账号一致。打印时间是否与打印服务器事件日志中的提交时间相差在 10 秒以内。这一步通常能发现两类问题一是中文文档名编码错乱二是 EMF 页数与 PDF 真实页数不一致PDF 最后一页空白被驱动忽略属于正常情况按打印机会计口径算 4 页即可。6.3 我的习惯每次搭打印解析流程都强制先造 5 个可控任务再动生产数据起初我开发第一版打印监控工具时直接拿生产打印服务器的历史 SPL 来做测试结果解析结果的页数和打印机实际计数对不上排查了整整一天最后发现是 SHD 版本判断错了而不是页数算法的问题。白费了一整天的情绪和时间。从那以后我每次搭解析流程都强制先造 5 个可控打印任务再动生产数据1 页纯文本、2 页带图片的 PPT、3 页PDF、1 页重复打印 5 份、1 个故意取消的任务。这五个用例覆盖了单页、多页、份数、文档大小、取消留痕五种典型状态全部跑通后再把脚本挂到生产环境。解析 SPOOL 文件不是那种看一篇文档就能一把过的事版本差异、驱动差异、时序差异都会让结果静默出错但只要有这几个固定用例垫底每次改代码都能在 5 分钟内确认“没改坏东西”。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

STAR方法+Harvard 10类行动动词:resume-template简历模板Experience部分写作完全指南

STAR方法+Harvard 10类行动动词:resume-template简历模板Experience部分写作完全指南

【免费下载链接】resume-template The best LaTeX resume template. 项目地址: https://gitcode.com/gh_mirrors/resumetemplate3/resume-template 点击查看 免费下载 简历的 Experience(经验)部分 是招聘官花最多时间、却最容易写砸的地方。…

📅 2026/10/11 13:41:32
从零设计一个消息中间件:高性能、高可用、数据不丢失

从零设计一个消息中间件:高性能、高可用、数据不丢失

技术分享 消息中间件架构设计核心命题:如果让我从零设计一个消息中间件,应该如何一步步推导出它的存储结构、消费模型、分布式架构与可靠性机制?一、设计目标与核心问题消息中间件的本质很简单:生产者生产消息,消费者…

📅 2026/10/11 13:41:32
编译原理课程设计报告写作指南:从技术决策到可验证实现

编译原理课程设计报告写作指南:从技术决策到可验证实现

简介:本资源为重庆理工大学《编译原理》课程设计报告,面向计算机专业本科生及编译技术初学者,聚焦编译器全流程开发实践,解决理论理解与工程实现脱节问题。报告完整覆盖词法分析、语法分析、语义分析、中间代码生成、优化及目标代…

📅 2026/10/11 13:36:31
MORE NEWS

更多资讯

📰

从源码构建HaleHound-CYD:PlatformIO多环境编译、OTA升级与Python版本陷阱完整指南

【免费下载链接】HaleHound-CYD ESP32-DIV HaleHound Edition for Cheap Yellow Display - Multi-protocol offensive security toolkit 项目地址: https://gitcode.com/gh_mirrors/ha/HaleHound-CYD 点击查看 免费下载 HaleHound-CYD 是一款运行在 ESP32 Cheap Ye…

📰

Agent基础——HTTP API

假设现在我们的Agent需要向工厂服务器查询设备的数据,这时候可以通过工厂服务器提供的接口进行查询,大致过程如下图所示:1.了解HTTP API首先,我们要先了解什么是HTTP API?我们可以简单的将其理解为:程序通过…

📰

基于YOLOv5的猪脸目标检测实战:数据采集、模型训练到TensorRT部署

简介:基于YOLOv5的猪脸目标检测项目以PyTorch为框架,面向畜牧智能化管理场景,可服务于猪只健康监测、个体识别与行为分析,适配有一定深度学习基础并希望落地目标检测应用的开发者。压缩包共236个文件,大小约70.75MB&am…

📰

Python利用支持向量机SVM进行时间序列预测:数据+源码实战

简介:这份资源面向希望用Python实现时间序列预测的开发者与数据分析学习者,聚焦支持向量机(SVM)在回归预测场景中的落地应用。包内共2个文件,包含1个py源码与1个xlsx数据文件,压缩包约34KB,源码…

📰

AI Toolbox Skills 技能管理完整教程:从 Git 安装到按工具同步,一键搞定

【免费下载链接】ai-toolbox Personal AI Toolbox 项目地址: https://gitcode.com/gh_mirrors/aitoolbo/ai-toolbox 点击查看 免费下载 AI Toolbox 是一款跨平台个人 AI 工具箱,其中的 Skills 技能管理模块可以帮你把 AI 编程技能从 Git 仓库或本地目录…

📰

Postgres主从流复制+pgpool高可用方案:从WAL原理到Failover实操

简介:一份针对 PostgreSQL 高可用架构的完整方案文档,面向数据库运维与架构设计工程师,重点解决基于 WAL 流复制搭建主从库、实时数据同步,以及结合 pgpool-II 实现连接池管理、读写分离与故障自动切换的问题。文档详细介绍了同步…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬