Access VBA应用前端启动自动检测并下载更新的实现方案咨询
Access 前后端分离架构下前端自动更新实现方案
整个方案的核心前提是Access运行时会锁定当前打开的FE文件,无法在VBA代码运行过程中直接替换自身文件,必须通过「启动前置检测+外置脚本中转替换」的思路实现,全程不需要用户手动操作。
前置准备
- 统一共享更新目录:搭建所有客户端都可访问的局域网共享文件夹,专门存放最新版FE文件(建议编译为accde格式避免源码被修改)、版本标识文件,给普通用户分配只读权限,仅管理员有写入发布权限。
- 版本标识规则:在共享目录根目录放一个纯文本文件
version.txt,第一行写最新版本号(建议用点分数字格式,比如1.2.5);同时在每个FE文件里建一张本地系统配置表Sys_Config,存当前FE自身的版本号。 - 本地缓存目录:统一使用用户目录下的AppData路径做更新缓存,比如
%APPDATA%\你的应用名\update\,避免C盘Program Files等目录的权限问题导致写入失败。 - 启动入口配置:建名为
AutoExec的自动启动宏,宏的第一个操作就是调用更新检测函数,不要等主窗体、业务模块、BE连接加载完再检测,避免后续退出时文件被占用。
核心执行流程
- FE启动后第一时间运行更新检测函数,先尝试访问共享更新目录,如果访问失败(比如用户离线、网络不通)直接跳过更新,正常启动应用。
- 分别读取本地FE存储的版本号、共享目录
version.txt里的最新版本号做字符串比对,如果版本一致直接进入主界面,无需更新。 - 如果检测到新版本,弹出提示告知用户需要更新重启,用户确认后将共享目录里的最新FE文件复制到本地更新缓存目录。
- 在缓存目录生成一个临时bat脚本,脚本逻辑为:等待几秒确保Access进程完全退出→将缓存目录的新FE文件覆盖到用户本地的FE存放路径→重新启动覆盖后的新FE文件→脚本自删除不留垃圾文件。
- 用Shell命令静默执行这个bat脚本,立刻执行
Application.Quit关闭当前Access实例,后续替换、重启操作全由脚本自动完成。
参考实现代码
在VBA标准模块里加如下代码,注意兼容32/64位Office:
' 放到模块顶部的声明部分 #If VBA7 Then Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) #Else Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) #End If Function RunUpdateCheck() Dim localVer As String, remoteVer As String Dim shareRoot As String, localFEPath As String, cachePath As String Dim batPath As String, batContent As String ' 配置项,可根据实际项目修改 shareRoot = "\\你的文件服务器\应用更新目录\" ' 共享更新目录路径 cachePath = Environ("APPDATA") & "\YourAppName\update\" localFEPath = CurrentProject.FullName ' 检测共享目录是否可访问,访问失败直接跳过更新 On Error Resume Next remoteVer = FreeFile Open shareRoot & "version.txt" For Input As #remoteVer If Err.Number <> 0 Then Err.Clear ' 打开主窗体,正常启动 DoCmd.OpenForm "Frm_Main" Exit Function End If Line Input #remoteVer, remoteVer Close #remoteVer On Error GoTo 0 ' 读取本地版本 localVer = Nz(DLookup("ConfigValue", "Sys_Config", "ConfigKey='CurrentVersion'"), "0.0.0") ' 版本一致无需更新 If remoteVer <= localVer Then DoCmd.OpenForm "Frm_Main" Exit Function End If ' 提示用户更新 If MsgBox("检测到新版本 v" & remoteVer & ",应用将自动更新并重启,请确认已保存当前操作。" & vbCrLf & "是否现在开始更新?", vbYesNo + vbInformation, "版本更新") = vbNo Then DoCmd.OpenForm "Frm_Main" Exit Function End If ' 创建缓存目录 If Dir(cachePath, vbDirectory) = "" Then MkDir cachePath ' 复制最新FE文件到缓存 FileCopy shareRoot & "app.accde", cachePath & "app_new.accde" ' 生成替换脚本 batPath = cachePath & "do_update.bat" batContent = "@echo off" & vbCrLf batContent = batContent & "ping 127.0.0.1 -n 3 >nul" & vbCrLf ' 等待3秒,确保Access完全退出 batContent = batContent & "copy /y """ & cachePath & "app_new.accde"" """ & localFEPath & """" & vbCrLf batContent = batContent & "start """" """ & localFEPath & """" & vbCrLf batContent = batContent & "del /f /q ""%~f0""" ' 脚本自删除 Open batPath For Output As #1 Print #1, batContent Close #1 ' 静默执行脚本,退出当前Access Shell batPath, vbHide Application.Quit acQuitSaveNone End Function
避坑说明
- 不要让多个用户直接打开共享目录里的同一个FE文件,必须把FE分发到每个用户的本地磁盘运行,不然会出现文件锁定导致更新替换失败,同时多人共享打开FE还会出现性能差、偶发损坏的问题。
- 发布新版本时,先把新的accde文件上传到共享目录,确认文件传输完成后再修改
version.txt里的版本号,避免用户检测到更新时复制到未传完的损坏文件。 - 如果项目有额外的依赖文件(比如dll、ocx控件、模板文件),可以把这些文件和FE一起打包,更新时同步复制到对应目录,注意注册dll的逻辑也可以放到bat脚本里执行。
- 版本号不要带中文、特殊字符,尽量统一用数字+点的格式,避免字符串比对逻辑出错。
- 如果需要强制更新,把更新提示的选择框去掉,检测到新版本直接走更新流程即可,不需要用户确认。
内容的提问来源于stack exchange,提问作者Richard Mahendeka
相关产品推荐
相关产品推荐

