COM+ATL实战:为Windows资源管理器自定义工具条

发布时间:2026/10/9 1:54:35

COM+ATL实战:为Windows资源管理器自定义工具条 简介面向Windows平台开发者和对COM/ATL感兴趣的C程序员这是一套可直接编译的Shell Extension源码工程目标是给Windows资源管理器添加自定义工具条。项目主干围绕COM组件设计展开包含ShellServer主组件、ViewObj、FolderObj、ShellListView等核心模块分别处理Shell视图、文件夹对象与列表视图的交互同时提供resource.h、maindlg.cpp等界面相关代码toolbar.bmp定义工具栏按钮位图rgs脚本和def文件负责组件注册与导出idl用来声明COM接口并生成类型库。整包共33个文件涵盖h、cpp、c、idl、rgs、rc、dsp、dll、tlb等类型压缩后仅67KB属于轻量级参考工程方便在Visual Studio中直接打开研读。已有252人浏览学习。通过这个工程可以完整理解从接口定义、类工厂实现到DLL注册的Shell扩展开发流程并可直接借鉴其模块划分结合自己的需求扩展出右键菜单、自定义工具栏或文件夹视图增强功能。对于刚接触Shell扩展的开发者这是一份难得的可运行样例。1. 这个 zip 到底解决什么问题COMATL 给资源管理器加工具条的土办法如果你手上有一份命名成com atl shell extension给windows资源管理器添加个工具条.zip的源码包先别急着双击运行因为这不是解压就能用的成品而是一个需要你自己编译、注册、调试的 C 工程。它要解决的问题很具体在资源管理器窗口内嵌一条常驻工具条放几个按钮点一下就能执行内部命令或打开某份文档省去反复切窗口、翻桌面图标的动作。核心并不是那些按钮逻辑而是 怎么让资源管理器认领一个自定义工具条这正是 COM 和 ATL 的用武之地。很多开发者第一次玩 Shell 扩展时会踩同一个预期以为写个普通 DLL用 regsvr32 注册一下就完事了。但资源管理器本身是一个 COM 容器它只认实现了特定接口的 COM 对象不认普通导出函数。工具条扩展得同时实现站点接口、窗口行为、持久化接口还要在注册表里声明自己的工具条分类缺一个环节菜单里就看不到你。这篇文章从原理讲到工程结构再给你五个真实踩坑记录基本覆盖把这个 zip 里的方案跑通、跑稳的全过程。2. 原理先行Shell 扩展与资源管理器工具条的工作方式2.1 资源管理器为什么是一个 COM 容器把工具条当插件挂进去资源管理器进程 explorer.exe 在启动和打开新窗口时会扫描注册表里若干固定分类下的 CLSID像插件列表一样枚举出来。当你把鼠标放到工具栏区域的右键菜单上Explorer 会按照分类去创建这些 COM 对象然后逐个询问它们想显示成什么样的小窗口。这个过程完全走 COMCoCreateInstance 创建对象、QueryInterface 检查接口、SetSite 传递宿主上下文、GetBandInfo 索取尺寸和样式。你的工具条本质上是一个进程内 COM 服务器宿主是 Explorer而不是你的独立程序。既然宿主是 Explorer你的扩展就必须严格遵守 COM 的规矩。引用计数、接口协商、HRESULT 返回值一个都不能错。比如 SetSite 传进来的 IUnknown 指针你需要 QueryInterface 成 IShellBrowser 才能获取到资源管理器的菜单栏、窗口句柄和命令状态。如果这一步拿不到后续所有按钮、菜单操作都会失去目标。这也是为什么标题里的 com 不是修饰词而是整个扩展的生命线。理解了这条调用链后面看注册表项就脉络清晰很多。2.2 手写 COM 太累ATL 模板帮你省了什么按照纯 C 手写一个 COM 服务器你要自己维护 IUnknown 三个方法的引用计数、实现 IClassFactory、写 DllGetClassObject 和 DllCanUnloadNow还要在 DLL 卸载时管住全局锁。这些样板代码跟你的业务逻辑半毛钱关系都没有却是所有 COM 组件能跑起来的前提。ATL 模板把这些全部封装成宏和模板基类让你只关心业务接口。以工具条扩展为例ATL 的 CComObjectRootEx 负责引用计数和聚合支持CComCoClass 替你生成类工厂DECLARE_REGISTRY_RESOURCEID 把注册表信息放进资源文件 .rgs 里编译时自动嵌入。我的经验是用 ATL 写这种 Shell 扩展头文件里最核心的代码就是几个宏和接口声明业务逻辑反而是集中在消息处理和配置读写上。下面是一段典型的 ATL 工具条类声明可以看到 COM 样板几乎被压缩成宏了// MyBand.h : 工具条 COM 对象的主接口声明 #include shlobj.h #include atlbase.h #include atlcom.h class ATL_NO_VTABLE CMyBand : public CComObjectRootExCComSingleThreadModel, public CComCoClassCMyBand, CLSID_MyBand, public IObjectWithSite, public IDeskBand, // 工具条核心接口 public IPersistStream // 持久化接口用于保存配置 { public: CMyBand() : m_bDirty(FALSE), m_bSiteSet(FALSE), m_dwBandID(0), m_dwViewMode(0) { m_size.cx 220; // 初始宽度像素 m_size.cy 40; // 初始高度 } DECLARE_REGISTRY_RESOURCEID(IDR_MYBAND) // 注册数据取自 .rgs 资源 DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMyBand) COM_INTERFACE_ENTRY(IObjectWithSite) COM_INTERFACE_ENTRY(IDeskBand) COM_INTERFACE_ENTRY(IPersistStream) END_COM_MAP() // IObjectWithSite STDMETHOD(SetSite)(IUnknown* pUnkSite); STDMETHOD(GetSite)(REFIID riid, void** ppvSite); // IDeskBand 以及父接口 IOleWindow STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode, DWORD dwFlags, DESKBANDINFO* pdbi); STDMETHOD(GetWindow)(HWND* phwnd); STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode); // IPersistStream STDMETHOD(GetClassID)(CLSID* pClassID); STDMETHOD(IsDirty)(void); STDMETHOD(Load)(IStream* pStm); STDMETHOD(Save)(IStream* pStm, BOOL bClearDirty); STDMETHOD(GetSizeMax)(ULARGE_INTEGER* pcbSize); private: CComPtrIUnknown m_spSite; // explorer 传来的宿主站点指针 CComPtrIShellBrowser m_spBrowser; // 从站点查询出的浏览器接口 HWND m_hWnd; // 工具条真实窗口句柄 SIZE m_size; // 工具条大小 BOOL m_bDirty; BOOL m_bSiteSet; DWORD m_dwBandID; DWORD m_dwViewMode; };这个声明里 BEGIN_COM_MAP 到 END_COM_MAP 的作用是告诉 ATL外部 QueryInterface 时哪些接口可以被查询到。IDeskBand 本身继承自 IOleWindow所以 COM 映射里只需要写 IDeskBandQueryInterface 时会自动把它当作 IOleWindow 处理。注意类 ID 使用的 CLSID_MyBand 是通过 DECLARE_REGISTRY_RESOURCEID 与 .rgs 资源关联的你在工程里一定要替换成自己生成的新 GUID。2.3 工具条的两种形态Desk Band 和 Explorer Bar 怎么选在 Shell 扩展体系里往资源管理器塞一条面板至少有两种常见形态Desk Band 和 Explorer Bar。Desk Band 是横向或竖向的工具栏通常贴在窗口的顶部、底部或两侧适合放按钮、下拉框、状态信息Explorer Bar 是侧边栏面板比如文件夹树、收藏夹、搜索面板适合放导航型内容。你手里的 zip 标题既然明确写着 工具条那八成是 Desk Band 方向。形态典型位置内容倾向适合场景Desk Band窗口顶部/底部/侧边按钮、输入框、状态区工具条、快捷动作、自定义控制Explorer Bar左侧/右侧垂直栏树形导航、列表、富页面导航面板、资源分类、辅助信息选型标准很简单如果扩展主要是一行按钮触发动作选 Desk Band如果扩展主要是一块面板展示层级内容选 Explorer Bar。后面几章我们围绕 Desk Band 展开因为对大多数人来说这个形态的代码量最小效果最直接。理解了形态差异后再打开工程文件就不会把两个方向的接口混在一起。3. 动手前工程结构、GUID 与注册表项3.1 解压后先看哪几个文件ATL 工程的关键组成打开这种 zip你通常能看到一个标准 ATL 工程的骨架不需要急着改逻辑先把文件职责分清楚。下面是一张常见文件清单按重要性排文件职责你要做什么解决方案与工程文件定义编译目标、平台与依赖先确认工程能编译出 DLL主头文件CMyBand 类声明与 COM 映射改 GUID、调接口方法主源文件接口方法的具体实现写工具条的业务逻辑.rgs 文件注册表脚本编译时嵌入资源检查 CATID 和 CLSID.rc 与 resource.h管理图标、字符串、对话框模板给工具条做界面资源.def 文件指定 DLL 导出函数一般不用动我拿到这类工程的第一件事是打开 .vcproj 或 .vcxproj确认 ATL 库已经被正确链接然后看 .rgs 里的 CLSID 是不是还写着示例值。如果是示例值整个编译和注册链路都会出问题因为资源管理器里可能有别的扩展撞了 GUID。记住Shell 扩展的 GUID 是身份标识不能复用示例也不能随手复制网上贴的代码。3.2 三个核心接口的 ATL 实现SetSite、GetBandInfo、Load/Save接口方法的实现是工具条是否出现的分水岭。SetSite 负责接收 Explorer 传来的站点指针并在卸载时接收 NULLGetBandInfo 负责向宿主汇报工具条尺寸和视图模式Load 和 Save 负责配置持久化。这三个方法里SetSite 和 GetBandInfo 缺一不可。下面是方法实现的常见骨架// MyBand.cpp : 核心接口方法实现 STDMETHODIMP CMyBand::SetSite(IUnknown* pUnkSite) { // 卸载时会传入 NULL此时释放全部接口引用 if (pUnkSite nullptr) { m_spBrowser.Release(); m_spSite.Release(); m_bSiteSet FALSE; return S_OK; } m_spSite pUnkSite; // 从站点指针换出 IShellBrowser后续按钮命令都要用它 HRESULT hr pUnkSite-QueryInterface(IID_PPV_ARGS(m_spBrowser)); if (FAILED(hr)) { OutputDebugStringW(LMyBand: QI IShellBrowser failed\n); return E_FAIL; } m_bSiteSet TRUE; OutputDebugStringW(LMyBand: SetSite OK\n); return S_OK; } STDMETHODIMP CMyBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DWORD dwFlags, DESKBANDINFO* pdbi) { m_dwBandID dwBandID; m_dwViewMode dwViewMode; if (pdbi nullptr) return E_INVALIDARG; if (dwFlags DBIF_VIEWMODE_VERTICAL) { // 宿主要求竖排高度和宽度反过来用 pdbi-ptMinSize.x m_size.cy; pdbi-ptMinSize.y m_size.cx; pdbi-ptMaxSize.y -1; // 允许拉高 } else { // 横向工具条最小尺寸直接取自 m_size pdbi-ptMinSize.x m_size.cx; pdbi-ptMinSize.y m_size.cy; pdbi-ptMaxSize.x -1; // 宽度可拉伸 } pdbi-wStyle DBIF_RESIZABLE | DBIF_BREAKBAR; // 可调整大小允许拆行 pdbi-dwModeFlags DBIMF_NORMAL; return S_OK; } STDMETHODIMP CMyBand::Load(IStream* pStm) { // 从流里读回 m_size、按钮布局等配置 ULONG cbRead 0; pStm-Read(m_size, sizeof(m_size), cbRead); m_bDirty FALSE; return S_OK; } STDMETHODIMP CMyBand::Save(IStream* pStm, BOOL bClearDirty) { // 把当前配置写进流Explorer 会替我们管理存储位置 ULONG cbWritten 0; pStm-Write(m_size, sizeof(m_size), cbWritten); if (bClearDirty) m_bDirty FALSE; return S_OK; }代码说明SetSite 里的 QueryInterface 是整条调用链的咽喉失败几乎全是注册表或线程模型问题。GetBandInfo 里最容易被忽略的是 ptMaxSize 字段横排时把 x 设为 -1 表示宽度允许拉伸竖排时 y 设为 -1。Load 和 Save 使用 Explorer 提供的 IStream 读写配置m_bDirty 标记用来告诉宿主 我的配置变了。3.3 注册表里必须写哪些键CLSID、InprocServer32、Implemented Categories要让资源管理器在工具栏菜单里枚举到你的扩展.rgs 里不能只有基础类注册还必须声明它属于 Desk Band 分类。下面是一份最小 .rgs 写法注意角括号和变量名是 ATL 的替换规则// MyBand.rgs : ATL 编译时会自动把 %MODULE% 替换为 dll 完整路径 HKCR { NoRemove CLSID { ForceRemove {YOUR-GUID-HERE} { InprocServer32 s %MODULE% { val ThreadingModel s Apartment } Implemented Categories { // CATID_DeskBands声明这是一个桌面工具条扩展 {00021492-0000-0000-C000-000000000046} s } } } }这里最关键的一行就是 Implemented Categories 下的{00021492-0000-0000-C000-000000000046}。这个固定 GUID 是 Desk Band 分类的标识Explorer 在枚举工具栏时只认这个分类。如果你的 .rgs 缺了它注册表里就算有 CLSID菜单里也找不到你的工具条。另外ThreadingModel 用 Apartment 对 Desk Band 来说比较稳妥因为 Explorer 的工具条都在主线程的单元里加载。4. 让工具条真正显示出来注册、启用与验证4.1 用 regsvr32 注册为什么每次都要管理员权限编译生成的 DLL 不能直接拷贝到系统目录Shell 扩展要先通过 regsvr32 注册让注册表知道 CLSID 与 DLL 路径的对应关系。注册命令必须在管理员权限的命令行里运行因为涉及的根键在 HKCR 或 HKLM 下普通权限只能写 HKCU而 Explorer 的工具栏枚举默认走的是 HKCR:: 以管理员身份打开命令提示符再执行 regsvr32 /s C:\MyProject\Debug\MyBand.dll :: 注册成功后自查注册表是否写全 reg query HKCR\CLSID\{YOUR-GUID-HERE} /s/s 参数是静默模式成功后不会有弹窗适合集成到构建脚本里。如果注册失败建议先去掉 /s 执行一次它会弹出具体错误码比如模块找不到、入口点不存在、权限不足。最重要的是每次重新编译后都要重新注册因为 DLL 路径里多了版本号或 Debug/Release 目录变化注册表不会自动跟随。4.2 在资源管理器里启用工具条从哪里打开注册完 DLL 后打开任意文件夹窗口在工具栏区域空白处右键会弹出一个带工具栏子菜单的列表。你的扩展名称会出现在里面选中后工具条窗口就会自动挂载到资源管理器窗口上。如果右键菜单里没看到就先关闭所有资源管理器窗口再重新打开有时候 Explorer 的枚举缓存不会立即刷新。在较新的 Windows 版本里菜单入口可能在查看菜单的工具栏分支下具体名字取决于你工程里的字符串资源。这个阶段如果菜单出现了但选中后没反应问题多半不在注册表而在 GetBandInfo 或窗口创建上。先把工具条子窗口创建逻辑写对让 GetWindow 能返回一个有效窗口句柄。不要一上来做复杂界面先放一个 CreateWindow 的白底子窗口确认能被 Explorer 接纳再往上堆按钮。4.3 验证加载用调试输出看 SetSite 和 GetBandInfo 有没有被调用Shell 扩展跑在 explorer.exe 进程里没有办法像普通程序一样直接附加调试器但可以用 OutputDebugString 把调用日志打出来再用调试器或系统调试输出工具查看。关键是确认两件事SetSite 否被调用IShellBrowser 是否拿到。下面的代码是 SetSite 里加日志的姿势STDMETHODIMP CMyBand::SetSite(IUnknown* pUnkSite) { if (pUnkSite nullptr) { OutputDebugStringW(LMyBand: SetSite(NULL), unloading\n); return S_OK; } OutputDebugStringW(LMyBand: SetSite called\n); HRESULT hr pUnkSite-QueryInterface(IID_PPV_ARGS(m_spBrowser)); if (FAILED(hr)) { OutputDebugStringW(LMyBand: QI IShellBrowser FAILED\n); return E_FAIL; } OutputDebugStringW(LMyBand: QI IShellBrowser OK\n); m_bSiteSet TRUE; return S_OK; }这一步是快速定位的关键。如果日志里只出现 SetSite called 但没有 QI OK说明接口映射有问题如果连 SetSite 都没有说明 Explorer 根本没有加载你的对象去查注册表和分类。如果 SetSite(NULL) 出现那是正常卸载不要当成错误。5. 避坑 / 常见问题 / 排查工具条不显示的 5 个真实案例5.1 注册成功但右键菜单没有工具条我最初调试时遇到的现象是regsvr32 明明提示成功reg query 也能查到 CLSID但右键工具栏菜单里就是没有我的扩展。排查到最后发现是 Implemented Categories 这个键写错了我把 CATID 写成了 InfoBand 的分类值Explorer 在 Desk Band 分类下自然找不到。原因就是 .rgs 里少了或写错了那个关键 GUID而 ATL 编译时并不会对分类 ID 做合法性校验。解决方法是打开 .rgs 文件确认{00021492-0000-0000-C000-000000000046}一字不差然后重新编译注册。宁可少写一个中括号也不要记错分类号。5.2 编译时报 DLL 被锁定无法覆盖写 Shell 扩展最烦的就是工程编译提示 无法打开 xxx.dll 或 LNK1104因为上一次的 dll 还被 explorer.exe 锁着。原因是 Shell 扩展一旦加载DLL 文件就被资源管理器进程引用住你在编译器里覆盖不了。解决方法是重启资源管理器注意不要直接在任务管理器里结束进程应该右键点击资源管理器后选重新启动。重启后桌面图标和任务栏会闪一下但 explorer 会重新拉起DLL 锁也会释放。如果重启不行那就注销一次这是最稳妥的后悔药。5.3 工具条一开就闪退窗口直接消失现象菜单里能看到扩展勾选后工具条闪现一下就没了没有崩溃弹窗。原因通常不是 COM 接口坏了而是 GetWindow 返回的窗口句柄无效或者窗口父窗口设置不对。最常见的错误是直接在 GetBandInfo 里创建模态对话框而 Desk Band 要求的是子窗口不能用对话框的模态循环。解决方法是工具条窗口用 CreateWindowW 创建父窗口传一个后续通过 GetWindow 返回的有效句柄并且窗口过程里要处理 WM_CREATE 和 WM_SIZE。可以在 GetBandInfo 里只设置尺寸在 GetWindow 里再创建这里面的调用顺序是 Explorer 自己控制的你不能事先假定。5.4 32 位与 64 位注册混乱你编译了一个 x64 的 DLL却用系统默认的 regsvr32 注册结果菜单里找不到。原因在于 64 位系统上有两套 regsvr32System32 下是 64 位SysWOW64 下是 32 位。Shell 扩展的 DLL 位数必须和 regsvr32 位数匹配注册表项才会写到正确的节点。解决办法是如果工程编译的是 64 位 DLL就显式用C:\Windows\System32\regsvr32.exe注册如果是 32 位 DLL用C:\Windows\SysWOW64\regsvr32.exe。记住这只和调试环境有关部署到目标机器时要保证 Shell 扩展位数和系统位数一致否则直接翻车。5.5 工具条显示出来了但按钮点了没反应这是最隐蔽的坑SetSite 成功工具条也出来了但按钮点击后调不到你的业务逻辑或者命令执行后界面没有任何反馈。排查下来其实是按钮的 WM_COMMAND 处理里QueryInterface 得到的 IShellBrowser 指针已经失效了或者压根就是没检查 HRESULT 就往下走。解决方法是每次使用 m_spBrowser 前检查指针是否非空并且所有 Shell 接口调用都要检查返回值。用 ATL 的话把 m_spBrowser 传给一个帮助函数统一判断返回值并输出日志能省很多调试时间。记住Shell 扩展里的 COM 调用不是写普通程序失败是常态不检查 HRESULT 的代码都是自寻玄学。6. 从能用到好用给工具条加配置持久化与右键菜单基础工具条跑通只是第一步真正投入内部使用还需要把配置存下来。利用 IPersistStream 的 Save 和 Load你可以把工具条的宽度、按钮列表、最近打开过的路径写进 Explorer 管理的流里这样用户下次打开资源管理器工具条还是上次调整好的样子而不是每次回到默认尺寸。注意在 Save 里写完数据后把 m_bDirty 置为 FALSE不然宿主会认为配置没保存可能触发不必要的提示。另一个实用技巧是给工具条子窗口增加右键菜单提供关闭工具条和打开设置两个入口。关闭操作可以通过 SetSite 传给宿主的 IShellBrowser 来发起但更简单的做法是让用户从资源管理器菜单里取消勾选工具条自己只做一件事把当前鼠标位置换算成客户区坐标再 TrackPopupMenu。不要在这个子菜单里加载太重的东西Shell 扩展的每一处延迟都会影响整个资源管理器窗口的响应速度。部署到其他机器的验证方法很关键不要在自己开着开发工具的电脑上测试最好准备一台干净的虚拟机只装系统镜像和必要的运行库。在那台机器上 regsvr32 注册 DLL打开资源管理器确认工具条出现、按钮能触发、配置能保存然后重启资源管理器再确认配置还在。这样才能证明你的扩展不依赖开发环境的调试器或路径。我自己的习惯是先做一个最小 Desk Band 空窗口验证加载链路再往上叠按钮和配置逻辑。那次跳过最小验证直接写完整功能结果调试了三天才发现是注册表少了分类 ID。从那以后每次做 Shell 扩展我都先跑通一个空窗口再考虑界面和业务这招帮我躲开了无数翻车现场。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/9 1:54:35

context.vim:用语法树把当前代码上下文钉在窗口顶部

如果你也习惯在长文件里来回翻页,一定经历过那种“起了个大早,赶了个晚集”的迷失感:光标停在第 480 行,却怎么也想不起来当前这个函数叫什么,外层 if 的条件是什么,只能一遍遍跳回顶部再看一眼再跳下来。这…

2026/10/9 1:54:35

pi coding agent CLI:LLM API、agent loop 与 TUI 的极简融合实践

1. 从“pi”这个标题说起:一个极简命名背后的技术野心第一次看到“pi”这个项目标题,很多人会愣一下——是那个圆周率?还是树莓派?或者某个数学库?但如果你最近在关注 LLM 应用开发、coding agent CLI 或者 TUI 工具链…

2026/10/9 2:44:37

大模型学习路线图:12步小白也能轻松入门并收藏!

本文提供一张清晰的十二步大模型学习路线图,帮助读者从入门到落地高效搭建完整知识体系。路线涵盖Python基础、Transformer原理、提示词工程、LangGraph、LangChain、RAG、Agent、多Agent协同、私有化部署、多模态技术、量化技术和模型微调。建议按顺序学习&#xf…

2026/10/9 2:44:37

2026瓷砖一线品牌有哪些?家装瓷砖品牌推荐

2025年全国陶瓷砖产量掉了17.8%,现在行业开窑率连一半都不到。大家都在抢存量,挑瓷砖早就不只看花色和单价了。新国标GB/T 45817-2025把防污、耐磨这些指标分成了3A到5A三级。现在买砖得看品牌实力、制造产能、产品性能、研发技术、市场渠道、品牌口碑和…

2026/10/9 2:39:37

【回眸】上海金桥沪东考点低压电工实操考试体验

目录 前言 考试流程 总结 前言 26年9月20日,前往沪东考点进行低压电工实操考试。 考试之前准备还算充分,打听了一下大家考试出现问题的地方。 第一个是绝缘手套没戴,第二个是安全帽没规范佩戴,需要把安全帽的下颚带拉好&…

2026/10/8 10:03:18

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/8 10:03:20

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

2026/10/9 0:04:27

毕业论文初稿完成后首次进行AIGC疑似度自查的摸底与分流策略

毕业论文初稿完成后首次进行AIGC疑似度自查的摸底与分流策略当数万字的学位论文初稿经历开题、实验、问卷与多轮文献梳理最终成形时,绝大多数研究生都会面临一道全新的形式审查关卡:AIGC 疑似度排查。在高校毕业审核流程中,盲审前的文本检测通…

2026/10/9 0:04:27

食堂节能改造源头工厂,商用厨房设备焕新方案广受好评

商用厨房作为餐饮经营、单位供餐的核心后勤阵地,其设备配置、动线规划与运维体系直接决定后厨作业效率、运营成本与合规性。从基础的灶具、制冷存储设备,到油烟净化、水处理等配套系统,每一个环节的合理性都与食品安全、能耗管控、消防安全挂…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑