VB6 DAO 3.51突发随机文件访问错误(Error91等)求助
先说结论:这种代码没动、仅部分站点突发的随机问题,大概率是Windows更新调整了系统权限、组件兼容性或文件系统行为——毕竟老组件本身已经停止官方支持,系统更新很容易触发这类隐性兼容问题。下面是几个不用大改源码就能尝试的方案,按优先级排序:
1. 修复DAO 3.51和msxbse35.dll的组件注册
Windows更新偶尔会意外破坏老组件的注册状态,尤其是这类停止维护的库。让出问题的站点用管理员权限打开命令提示符,执行以下命令:
- 注册DAO 3.51:
regsvr32.exe "C:\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao351.dll" - 注册FoxPro驱动:Win10 64位用
regsvr32.exe "C:\Windows\SysWOW64\msxbse35.dll",Win7 32位用regsvr32.exe "C:\Windows\System32\msxbse35.dll"
如果注册失败,直接把这两个dll复制到你的程序安装目录(私有部署)再注册——这样能彻底避开系统级dll被更新影响的风险。
2. 强制程序以兼容模式运行 + 禁用UAC虚拟化
Windows更新后UAC规则经常会强化,导致程序访问文件时被偷偷重定向到虚拟目录(比如C:\Users\<用户名>\AppData\Local\VirtualStore),这就会出现“文件未找到”或者读写的不是你预期的文件。解决方法:
- 右键程序exe→属性→兼容性→勾选“以兼容模式运行这个程序”,选择Windows 7(针对Win10站点)
- 同时勾选“以管理员身份运行此程序”(也可以给程序加清单文件配置,避免用户手动操作)
- 禁用UAC虚拟化:在兼容性选项里点击“更改所有用户的设置”,确保“禁用UAC虚拟化”被勾选
3. 严格检查DAO对象的初始化和释放(解决Error 91)
Error 91(对象变量未设置)随机出现,大概率是对象释放不彻底导致的残留引用,或者并发访问时的对象状态异常。你只需要在现有代码里做微小调整:
- 所有DAO对象(比如
DBEngine、Database、Recordset)使用完后,必须显式执行Set xxx = Nothing,哪怕在错误处理分支里也要加 - 比如在操作数据库的子程序末尾,统一加清理代码:
On Error Resume Next If Not rs Is Nothing Then If rs.State = dbOpen Then rs.Close Set rs = Nothing End If If Not db Is Nothing Then If db.State = dbOpen Then db.Close Set db = Nothing End If On Error GoTo 0
- 避免在全局模块里持有DAO对象的引用,尽量“按需创建、用完即毁”
4. 添加文件访问的重试逻辑(解决“文件正在使用”)
随机的“文件正在使用”错误,可能是Windows更新后文件系统缓存机制变化,或者杀毒软件临时锁定了文件。给你的文件操作代码加个简单的重试:
Dim retryCount As Integer retryCount = 3 ' 最多重试3次 Do While retryCount > 0 On Error Resume Next ' 这里放你的DAO打开文件/执行操作的原有代码 If Err.Number = 0 Then Exit Do ' 操作成功就跳出循环 ' 只处理文件未找到或正在使用的错误 If Err.Number = 3265 Or Err.Number = 70 Then retryCount = retryCount - 1 Sleep 500 ' 等待500毫秒再重试,需提前声明:Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Else Err.Raise Err.Number ' 其他错误直接抛出,不重试 End If Loop On Error GoTo 0
这个改动只是在原有代码外套一层循环,完全不影响核心业务逻辑。
5. 禁用Windows快速启动(Win10站点)
Win10的快速启动会让系统处于半休眠状态,偶尔会导致文件系统的锁状态异常,对老格式的.mdb和.dbf文件影响尤为明显。让用户关闭快速启动:
- 控制面板→电源选项→选择电源按钮的功能→更改当前不可用的设置→取消勾选“启用快速启动(推荐)”
6. 检查杀毒/安全软件的拦截
部分站点的杀毒软件可能在Windows更新后升级了规则,把你的程序识别为可疑行为,拦截了文件访问。让用户把程序安装目录和数据库文件目录添加到杀毒软件的白名单里。
这些方案全部基于“最小改动源码”的原则,大部分是系统配置或组件修复,需要改代码的地方也只是加对象释放和重试逻辑,完全不用迁移到ADO或VB.NET。建议先从组件注册和兼容模式开始尝试,这两个已经解决过很多类似的老VB6程序问题。
内容的提问来源于stack exchange,提问作者finch

