首页 / 资讯中心 / 文章详情

VC6 FileTool.dll 修复添加工程文件假死与注册排查指南

VC6 FileTool.dll 修复添加工程文件假死与注册排查指南 ★ FEATURED ARTICLE
简介面向仍在使用 Visual C 6.0 的开发者这份兼容性工具包用于修复 VC6 在 Windows 7/10 下无法打开文件、不能添加工程文件的常见故障。压缩包共 51 个文件、约 4.9MB包含 cpp 与 h 源码、dsp 和 dsw 工程文件以及已编译的 dll、lib、obj、pdb 等发布与调试文件bmp 位图、rc 资源脚本和 tlb 类型库等则对应工具栏与 Add-in 注册信息结构较完整可直接使用或重新编译。已有 447 人学习关注说明该问题在老项目维护中仍有较高需求。读者可得到完整的 Add-in 工程源码、现成动态库及调试符号既能快速恢复 VC6 的文件菜单功能也便于研究 VC6 插件加载机制、排查注册失败与兼容性异常对搭建旧版开发环境和维护遗留工程有实际参考价值。尤其适合需要继续维护 VC6 遗留代码、在老系统上复现编译环境或学习经典 IDE 插件扩展方式的读者。1. VC6 里点一次“添加文件到工程”就假死FileTool 是那颗后悔药手上还压着 VC6 存量代码的人基本都遇到过这一幕Project → Add To Project → Files…对话框不出来IDE 窗口变灰任务管理器里 DevStudio 的 CPU 掉到 0只能结束进程重开。工程没坏坏的是 VC6 自带的那条文件选择链路在新系统上它已经走不通了。vc6.0 FileTool 添加工程文件这条老办法解决的正是这一个动作一个叫 FileTool.dll 的 DevStudio Add-in注册进 IDE 之后在工具栏上多出一个按钮点它走的是另一套文件选择逻辑选完直接把 .cpp、.h、.rc 塞进当前工程对应的分组里。它适合两类人一类是编译环境不能动、必须留在 VC6 里维护老代码的另一类是要给一批老机器快速恢复开发环境的。需要说清楚边界——它只解决“往工程里加文件”这一件事不解决编译器兼容性也不解决 Unicode 源码、C 标准这些问题。把它当成一颗针对性的后悔药别当成万能补丁。2. FileTool 挂在哪里Add-in 加载链路与三条接入路线2.1 自带的 Add To Project → Files 为什么会卡死先把故障现象拆开看不同表现对应不同的根因别一上来就重装 VC6。点完菜单之后如果 IDE 窗口不重绘、CPU 占用的数字一直贴着 0说明主线程卡在一个模态等待上多半是公共文件对话框在创建阶段就没返回如果 CPU 单核跑满、界面还能拖动那是死循环跟对话框无关得先查工程文件和 shell 扩展。VC6 这条链路老得比较彻底。它内部用的是早期版本的 MFC 和公共对话框在 Win7 之后系统 shell 整体换代旧接口在部分机器上初始化 OLE 时会挂起尤其是那些装了一堆右键菜单扩展、云盘同步钩子、输入法注入的机器公共对话框加载 shell 扩展时被第三方 DLL 拖住表现出来就是“点一下没反应”。我一般会先做一步排除把资源管理器里的第三方 shell 扩展临时停掉再试如果这时能弹出对话框那问题就不在工程上。还有一个容易被忽略的工程放在只读目录、网络映射盘或者受控目录下。对话框其实弹出来了选完文件后写 .dsp 失败界面切回来像是什么都没发生实际上是权限问题。所以排查顺序应该是——先确认是不是模态卡死再确认 shell 扩展最后确认工程目录的写权限别把三种问题混成一种。2.2 FileTool 走的是 DevStudio 对象模型这条路VC6 的 IDE 支持两类扩展一类是 Add-in编译成 DLL 的 COM 组件一类是 MacroVBScript 写的 .dsm 宏文件。IDE 启动时会去注册表里扫一遍 AddIns 键把里面的 DisplayName 列到 Tools → Customize → Add-ins and Macro Files 的列表里用户勾上之后IDE 才真正去 CoCreateInstance 创建这个组件再把一个 Application 对象IDispatch传给它的 OnConnection。FileTool 就是这一套。它不碰 IDE 原先那条“弹系统对话框再回填工程”的链路自己弹选择框、自己拿到选中的路径然后通过传进来的 Application 对象去访问活动工程的接口把文件按扩展名归档。所以它能在自带功能已经失效的机器上正常工作——两条路一条堵了另一条还通。这也解释了它为什么必须“注册”不注册IDE 扫不到这个键列表里就不会有这一项你连勾选的机会都没有。DLL 文件本身放在硬盘上不会自动生效注册表项才是那个开关。2.3 三条接入路线注册 DLL、宏文件、自己写同样是解决“加文件”这个诉求实际有三条路可选选错了会白折腾半天。路线前提优点局限注册 FileTool.dll拿到 32 位 DLL有本机管理员权限一次注册长期可用有工具栏按钮依赖 DLL 与注册表环境迁移要重做写 .dsm 宏文件会用 VBScript 调 DevStudio 对象模型不碰注册表随工程走每次要手动加载宏界面入口弱自研 Add-in有 32 位编译环境逻辑可定制能加批量导入开发成本高调试体验很差绝大多数情况走第一条。第二条适合那种连管理员权限都拿不到的受限机器写十几行 VBScript 调Application.ActiveProject.AddFile也能凑合但没有按钮每次都得从宏列表里点。第三条只在需要“按目录结构批量建筛选器”这类定制时才值得普通维护老工程没必要。3. 注册 FileTool.dll位数、目录、注册表三处必须对齐3.1 先确认 DLL 是 32 位再决定放哪VC6 是纯 32 位进程它只能加载 32 位 DLL。很多人手里那份 FileTool.dll 来源不明可能是从别处拷来的也可能是自己用高版本工具链重新编的位数不对注册时直接报错或者注册成功但 IDE 加载失败。所以第一步是把 DLL 的机器类型看清楚。echo off rem VC6 安装根目录按实际情况改Common 与 VC98 是同级目录 set VC6_ROOTC:\VS6 set DLL%VC6_ROOT%\Common\MSDev98\AddIns\FileTool.dll if not exist %DLL% ( echo [x] DLL 不在预期位置: %DLL% exit /b 1 ) rem dumpbin 随 VC6 一起装在 VC98\Bin 下 %VC6_ROOT%\VC98\Bin\dumpbin.exe /headers %DLL% | findstr /i machine/headers会把 PE 头打出来machine那一行是关键显示x86才是 32 位可以继续显示x64或者ARM64就说明这份 DLL 用不了换一份。这一步看着简单实际是踩坑率最高的一环——用 64 位 regsvr32 去注册 32 位 DLL系统会直接甩一个错误码而错误码本身完全看不出跟位数有关。放的位置也有讲究。VC6 的插件目录是安装根目录下的Common\MSDev98\AddIns和VC98同级。不要放在桌面、下载目录、带中文名的文件夹里更不要放在网络映射盘上——注册表里存的是绝对路径路径里一旦有中文或者盘符映射关系变化IDE 加载时就会失败而且失败得静悄悄。3.2 regsvr32 用哪个SysWOW64 与 UAC 提权在 64 位 Windows 上C:\Windows\System32\regsvr32.exe是 64 位版本C:\Windows\SysWOW64\regsvr32.exe才是 32 位版本。名字容易看反SysWOW64 里面装的恰恰是 32 位程序。注册 32 位 DLL 必须用后者否则会出现“已加载模块但找不到 DllRegisterServer 入口点”这类看着像 DLL 坏了的报错。echo off setlocal set DLL%VC6_ROOT%\Common\MSDev98\AddIns\FileTool.dll if %DLL% set DLLC:\VS6\Common\MSDev98\AddIns\FileTool.dll rem 64 位系统优先用 SysWOW64 下的 32 位 regsvr32 if exist %SystemRoot%\SysWOW64\regsvr32.exe ( set REG%SystemRoot%\SysWOW64\regsvr32.exe ) else ( set REG%SystemRoot%\System32\regsvr32.exe ) rem 先反注册清掉可能残留的旧路径 %REG% /s /u %DLL% rem 再注册/s 静默失败时 errorlevel 非 0 %REG% /s %DLL% if errorlevel 1 ( echo [x] register failed, errorlevel%errorlevel% echo 去掉 /s 再跑一次可以看到具体弹窗 ) else ( echo [ok] DllRegisterServer 调用完成 )参数含义/s静默不弹框适合脚本/u是反注册调的是DllUnregisterServer不带/s时会弹一个成功或失败的对话框排查阶段建议先手动跑一次不带/s的能直接看到 HRESULT。先反注册再注册这一步别省机器上残留的旧注册项指向一个已经不存在的路径时新注册未必能覆盖干净。UAC 是第二个坎。注册写的是 HKLM 下的键普通权限的 cmd 会直接返回 0x80070005。右键“以管理员身份运行”再执行或者在一个已经提权的终端里跑。这一步没提权脚本会“看起来跑完了”实际什么都没写进去。3.3 注册表核对DisplayName、Filename、LoadBehavior注册成功不等于 IDE 能看见。VC6 是 32 位进程读的是注册表的 32 位视图也就是 64 位系统上的WOW6432Node分支。如果手工往 64 位分支里写键regedit 里能看到VC6 就是扫不到——这种“明明有却读不到”的情况最费时间。用下面这段把两个视图都扫一遍看实际落在了哪里。# 用通配符跳过厂商标识键避免不同安装源下路径不一致 $patterns ( HKLM:\SOFTWARE\WOW6432Node\*\DevStudio\6.0\AddIns\*, HKCU:\SOFTWARE\*\DevStudio\6.0\AddIns\* ) $rows foreach ($p in $patterns) { Get-Item $p -ErrorAction SilentlyContinue | ForEach-Object { $props Get-ItemProperty $_.PSPath [pscustomobject]{ Key ($_.PSPath -replace ^.*Registry::, ) DisplayName $props.DisplayName Filename $props.Filename LoadBehavior $props.LoadBehavior } } } $rows | Format-List输出里重点看三个值。Filename必须是 DLL 的绝对路径且和实际位置一字不差路径里多一个空格都不行DisplayName是稍后出现在 IDE 勾选列表里的名字一般是 “FileTool Developer Studio Add-in” 这类LoadBehavior是控制是否随 IDE 启动自动加载的 DWORD常见取值 1 表示自动加载、0 表示需要手动勾一次不同来源的安装包默认值可能不一样以你机器上的实际值为准。如果Filename指向错误直接改这个值比重装快得多改完重启 IDE 就生效。如果整条键都不在 WOW6432Node 下而在 64 位分支下说明注册时用错了 regsvr32回 3.2 重来别手工搬键——搬过去 DllRegisterServer 写的其他附属项还是缺的。4. 把菜单栏调出来Add-ins and Macro Files 与工具栏自定义4.1 Tools 菜单里的 Add-ins and Macro Files注册表写对之后打开 VC6进 Tools → Customize切到 “Add-ins and Macro Files” 页。上面是 Add-ins 列表下面是 Macro Files 列表右边有 Browse。列表里应该出现刚才注册表里那个 DisplayName前面有个复选框。勾上点 Close。IDE 这时才会真正创建组件、调用 OnConnection工具栏上通常立刻多出一条按钮名叫 “Add Files to Project” 之类。如果列表里什么都没有别在这个对话框里耗时间回第 3 章查注册表和位数——这个页面读的就是那份注册表读不到就是没写对。有个细节值得说这个勾选状态会被 IDE 记到用户配置里所以“勾上一次以后就一直在”是正常的。反过来说如果每次重启都要重勾说明写用户配置那一步失败了多半是权限问题见 5.2。4.2 从 Customize 的 Toolbars 页把按钮拖到 File 菜单旁Add-in 加载出来之后入口不一定在你顺手的位置。VC6 的自定义能力其实够用Customize → Toolbars 页列表里会多出这条 add-in 的工具栏名勾上就显示取消就隐藏Customize → Commands 页类别下拉里会多出一个 “Add-ins” 分类里面就是它注册的命令选中之后可以直接拖到主菜单栏或者任意一条工具栏上。我一般会把它拖到 Project 菜单旁边或者干脆做成一个独立的小工具栏只放这一个按钮宽度压到最小贴在编辑区右上角。理由是加文件这个动作在维护老工程时是高频操作藏在两级菜单里不如一个按钮直接。位置操作路径适用独立工具栏Customize → Toolbars 勾选插件工具栏高频使用占用横向空间主菜单栏Customize → Commands → Add-ins 拖拽不想多一条工具栏Project 菜单内同上拖进下拉菜单和原生 Add To Project 放一起快捷键Customize → Keyboard 里给该命令绑键键盘流注意别和 IDE 默认键冲突工具栏被误关掉是最常见的“怎么突然没了”不是插件坏了。回 Toolbars 页勾回来即可如果勾选项都灰着说明这次 IDE 启动根本没加载 add-in还是回第 3 章。4.3 固化配置先提权勾一次再正常启动验证配置能不能留住取决于 IDE 有没有权限把加载状态写进用户配置。稳妥的做法是分两步第一次用管理员身份启动 VC6进 Customize 勾上 add-inClose然后正常退出 IDE第二次用平常的方式启动看工具栏还在不在、按钮能不能点。如果第二步失败说明加载状态没写进用户配置或者LoadBehavior被写成了 0。前者继续用管理员身份启动也能用只是每次都得提权后者直接把那个 DWORD 改成 1 再试。这两种处理方式都不算优雅但比重装一遍 VC6 省事得多。还有一层如果一台机器上有多个 VC6 安装比如不同盘符各一份注册表里那条Filename只会指向其中一份另一份启动时加载的还是同一份 DLL。这时候要么统一成一份安装要么每次切换时重新注册——后者非常容易忘忘一次就得排查半小时。5. 避坑与排查注册成功却点不出菜单的五个现场5.1 现象regsvr32 弹 0x80070005 或“找不到入口点”现象很直接命令行执行完弹窗报“模块已加载但找不到 DllRegisterServer 入口点”或者返回 0x80070005 拒绝访问。原因通常有两个。一是用错了 regsvr3264 位系统上直接敲regsvr32解析到的是 System32 下那个 64 位版本它加载 32 位 DLL 会在加载阶段就失败报错信息却长得像 DLL 本身损坏。二是没提权写 HKLM 时被 UAC 拦下返回的就是 0x80070005。解决办法固定成两步显式写全%SystemRoot%\SysWOW64\regsvr32.exe并且在一个已经提权的终端里执行。别指望“右键管理员运行”之后从资源管理器双击 DLL 能成那条路径调的 regsvr32 未必是你以为的那个。5.2 现象这次勾上了重启 IDE 又变回未勾选勾选当场生效关掉 VC6 再开Customize 里那一项又没打勾工具栏也消失了。原因是 IDE 把“已加载”这个状态写进用户配置时失败了。VC6 在 Win7 之后默认没有管理员权限写 HKCU 下某些位置或者写安装目录下的配置文件都可能被拒。表现出来就是“当下能用、下次就忘”。解法是先以管理员身份启动一次完成勾选后正常退出再以普通权限启动验证。仍不行就查LoadBehavior把它改成 1。这条我踩过不止一次最开始以为是 DLL 有问题反复重新注册其实是权限在作怪。5.3 现象按钮能点文件却被塞进了 Other Files选择框正常弹出文件也选上了但工程树里文件落在了 Other Files 或者根节点下没有进 Source Files / Header Files。这不是插件坏了是归档规则的问题add-in 按扩展名判断该往哪个分组放遇到它不认识的扩展名.inl、.hpp、自定义后缀就归到兜底分组。工程里如果手工改过筛选器名字也会对不上。解决办法是接受这个行为手工把文件从 Other Files 拖到目标筛选器VC6 会记住这次的归属并写进 .dsp。批量导入几十个文件时先用扩展名归类一遍再统一拖比一个个点快得多。5.4 现象以管理员跑 VC6 之后从资源管理器拖文件进 IDE 失效为了插件加载把 VC6 设成“以管理员身份运行”结果发现原来好用的拖拽不见了从文件夹里拖一个 .cpp 到编辑区毫无反应。原因是 Windows 的 UIPI 消息隔离低完整性级别的进程资源管理器不能往高完整性级别的进程提权的 VC6发窗口消息拖拽本质就是发消息。这跟 FileTool 一点关系都没有是提权本身的副作用。解决办法二选一要么接受没有拖拽、只用按钮加文件要么不设永久提权改成“第一次提权勾选、之后普通启动”用 4.3 那套流程。我个人倾向后者拖拽在整理老工程时太顺手舍不得。5.5 现象工具栏整条消失或者按钮一直是灰的某次启动之后工具栏条目还在列表里但勾不上或者按钮能看见却点不动。前者一般是这次 IDE 启动时 add-in 加载失败常见诱因是 DLL 被移动过、路径里带了中文、或者放在了一个盘符会变的网络位置上——注册表里存的是绝对路径路径失效就加载不了。后者多半是当前没有打开任何工程或活动工程是只读的命令本身要求有可写的活动工程。处理顺序先看注册表里Filename指的位置文件还在不在再看路径是不是纯 ASCII最后确认当前工作区里确实有一个可写的活动工程。这三步走完还不行反注册再重新注册一次比重装 IDE 划算。6. 批量落地把注册、勾选、验证压成一条流水线单台机器手工点几下就完了真正费时间的是给一批机器恢复环境。我的做法是把“定位目录 → 校验位数 → 提权注册 → 回读注册表”压成一个脚本跑完只看一个结果。echo off setlocal enabledelayedexpansion rem 全流程脚本注册 回读任一步失败立即退出 if %VC6_ROOT% set VC6_ROOTC:\VS6 set DLL%VC6_ROOT%\Common\MSDev98\AddIns\FileTool.dll rem 1. 文件存在性 if not exist %DLL% ( echo [x] missing: %DLL% exit /b 1 ) rem 2. 位数校验只放行 x86 %VC6_ROOT%\VC98\Bin\dumpbin.exe /headers %DLL% | findstr /i machine | findstr /i x86 nul if errorlevel 1 ( echo [x] not a 32-bit dll exit /b 2 ) rem 3. 提权检查net session 失败说明当前不是管理员 net session nul 21 if errorlevel 1 ( echo [x] run this as administrator exit /b 3 ) rem 4. 反注册后重新注册 set REG%SystemRoot%\SysWOW64\regsvr32.exe if not exist %REG% set REG%SystemRoot%\System32\regsvr32.exe %REG% /s /u %DLL% %REG% /s %DLL% if errorlevel 1 ( echo [x] DllRegisterServer failed exit /b 4 ) echo [ok] registered, now open VC6 and enable it in Customize endlocal逻辑很直白任何一步不满足就带错误码退出脚本不做“尽力而为”避免出现“跑完了但其实是半成品”的状态。第 3 步用net session判断是否提权比查 whoami 组列表快判断也够准。跑完之后按这张表逐项确认五项全过再交付检查点动作期望DLL 位数dumpbin 看 machine 行x86注册表视图查 WOW6432Node 分支存在对应 AddIns 子键Filename读该键的值绝对路径且文件存在IDE 列表Customize → Add-ins 页能看到对应条目实际动作打开老工程点按钮文件进入正确分组最后说一句我自己的习惯。早年给一台机器修这个图省事只跑了注册没做回读结果那台机器装的是定制版注册项落到了 64 位分支我在 IDE 里翻了半小时没找到最后才发现是视图问题。从那以后每次部署完我都强制走一遍回读那一步不管多急。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站