📄 140.htm
字号:
<p>VB实现应用程序在局域网上自动更新 </p>
<p></p>
<p> 我们在用VB开发大型应用程序时遇到如下问题,进入调试、维护阶段开发小组进驻用户单位,软件交用户试用会经常修改程序并重新编译。然后再由程序员给用户复制更新,或者通知用户自行复制更新。对于少量用户可以做到及时更新。而我们的一个用户在一座十层的大厦中办公,有十几个部门(即有管理部门又有生产车间分布在不同的楼层),每个部门少则有2~3台工作站,多则有数十台工作站,与四台服务器组成局域网络.且每个部门应用程序各不相同,应用程序修改编译后经常不能同步更新,从而造成部门内数据或者部门间的数据不一致。程序员每天都要跑上跑下检查版本更新程序浪费了很多宝贵时间,即使通知部门主管自行更新,某些工作站也会出现遗漏现象。鉴于以上问题我们考虑使用程序自动更新技术,即自动检查新版本,将新版本复制到本地,重新执行本地应用程序。</p>
<p></p>
<p> 基本原理:在某个服务器上共享出一个目录,其权限为程序员完全控制,其它用户只读。</p>
<p></p>
<p> 例如:\\NtServer01\Refresh,程序员重新编译后的应用程序.EXE都存放在此目录下。</p>
<p></p>
<p> 在应用程序的入口处调用版本检查及更新过程,如果服务器应用程序的修改时间大于本地应用程序的修改时间,则认为有新版本出现,应该将服务器上的新版本复制到本地硬盘。</p>
<p></p>
<p> 由于应用程序在运行时不能被新版本覆盖,所以就需要中介程序FastCopy.EXE(也用VB编写)来完成更新版本并重新运行本地应用程序。为了达到及时更新的目的可在应用程序中每隔5分钟或10分钟检查一次是否有新版本。(此部分略有兴趣的读者可自行编程添加)</p>
<p></p>
<p>本例中:</p>
<p></p>
<p> 服务器:NtServer01 共享目录: Refresh</p>
<p></p>
<p> 应用程序:MyApp.exe 中介程序:FastCopy.exe (都存储于共享目录中)</p>
<p></p>
<p> 具体程序实现如下:</p>
<p></p>
<p> 在应用程序工程MyApp中的部分代码如下:</p>
<p></p>
<p> Option Explicit</p>
<p></p>
<p> 注释:编译后的应用程序名称,注意没有后缀 .EXE,本例为MYAPP</p>
<p></p>
<p> Private Const App_Name = "MyApp"</p>
<p></p>
<p> 注释:最新的应用程序存放的路径,本例为:服务器 NtServer01 共享目录 Refresh</p>
<p></p>
<p> Private Const ExePath = "\\NtServer01\Refresh\"</p>
<p></p>
<p> 注释:中介程序名称,注意没有后缀 .EXE,本例为 FastCopy</p>
<p></p>
<p> Private Const MidExeName = "FastCopy"</p>
<p></p>
<p> 注释:应用程序入口</p>
<p></p>
<p> Private Sub Form_Load()</p>
<p></p>
<p> If UCase(Trim(App.EXEName)) <> UCase(Trim(App_Name)) Then</p>
<p></p>
<p> MsgBox "必须将订单管理系统的名称更改为: " + App_Name</p>
<p></p>
<p> End</p>
<p></p>
<p> End If</p>
<p></p>
<p> 注释:判断是否有最新版本的应用程序,如有则自动更新</p>
<p></p>
<p> Call ExeRefresh</p>
<p></p>
<p> 注释:下面为订单管理系统的正常操作 略 ... ....</p>
<p></p>
<p> End Sub</p>
<p></p>
<p> 注释:版本检查及更新过程</p>
<p></p>
<p> rivate Sub ExeRefresh()</p>
<p></p>
<p> 注释:定义四个临时字符串变量</p>
<p></p>
<p> Dim s1 As String</p>
<p></p>
<p> Dim s2 As String</p>
<p></p>
<p> Dim s3 As String</p>
<p></p>
<p> Dim s4 As String</p>
<p></p>
<p> On Error Resume Next</p>
<p></p>
<p> 注释:将本地应用程序MyApp.EXE的全路径名存入 s1</p>
<p></p>
<p> 注释:将本地中介程序FastCopy.exe的全路径名存入 s3</p>
<p></p>
<p> s1 = "TNT"</p>
<p></p>
<p> If Len(App.Path) > 3 Then</p>
<p></p>
<p> s1 = App.Path + "\" + Trim(App_Name) + ".exe"</p>
<p></p>
<p> s3 = App.Path + "\" + MidExeName + ".EXE"</p>
<p></p>
<p> Else</p>
<p></p>
<p> s1 = App.Path + Trim(App_Name) + ".exe"</p>
<p></p>
<p> s3 = App.Path + MidExeName + ".EXE"</p>
<p></p>
<p> End If</p>
<p></p>
<p> s4 = "TNT"</p>
<p></p>
<p> 注释:将本地应用程序MyApp.EXE文件的修改时间存入 s4</p>
<p></p>
<p> s4 = FileDateTime(s1)</p>
<p></p>
<p> s2 = "TNT"</p>
<p></p>
<p> 注释:将网络上应用程序MyApp.EXE文件的修改时间存入 s2</p>
<p></p>
<p> s2 = FileDateTime(ExePath + App_Name + ".EXE")</p>
<p></p>
<p> If s2 = "TNT" Then</p>
<p></p>
<p> MsgBox "没有找到最新的可执行文件:" + ExePath + App_Name + ".EXE" _ + vbCrLf + vbCrLf + "原因1:存放最新EXE的服务器或者工作站没有打开;" _ + vbCrLf + "原因2:存放最新EXE的路径错误或者EXE文件不存在;" _+ vbCrLf + "请将此情况通知程序员." + vbCrLf + vbCrLf _+ vbCrLf + "按确定按钮后,将继续运行本地EXE文件.", vbCritical, "提示"</p>
<p></p>
<p> End If</p>
<p></p>
<p> If s2 = "TNT" Or s4 = "TNT" Then Exit Sub</p>
<p></p>
<p> 注释:如果网络上应用程序MyApp.EXE文件的修改时间,大于本地MyApp.EXE文件的修改时间</p>
<p></p>
<p> 注释:然后再运行本地MyApp.EXE ,中介程序退出后,整个更新过程结束.</p>
<p></p>
<p> If CDate(s2) > CDate(s4) Then</p>
<p></p>
<p> 注释:将网络上的中介程序FastCopy.exe复制到本地,这样可防止本地无中介程序时无法进行更新</p>
<p></p>
<p> FileCopy ExePath + MidExeName + ".EXE", s3</p>
<p></p>
<p> 注释:则运行中介程序FastCopy.exe ,将最新的MyApp.EXE 复制到本地</p>
<p></p>
<p> s1 = Shell(s3 + " " + ExePath + "," + App_Name + ".EXE", vbNormalFocus)</p>
<p></p>
<p> 注释:本地应用程序MyApp.EXE 终止运行,否则已经更新的MyApp.EXE无法覆盖本地的MyApp.EXE .</p>
<p></p>
<p> End</p>
<p></p>
<p> End If</p>
<p></p>
<p> End Sub</p>
<p></p>
<p> 将以上程序编译为:MyApp.exe 存储在共享目录中.</p>
<p></p>
<p></p>
<p> 在中介程序工程 FastCopy 中的代码如下:</p>
<p></p>
<p> 向工程中增加一个窗体Form1 ,向Form1中添加一个定时器 Timer1 , 增加一个标签控件 Label1 ,其 Caption 为 "应用程序正在更新",并调整窗体大小.</p>
<p></p>
<p> Option Explicit</p>
<p></p>
<p> Private sPath As String 注释:用于存储服务器上的共享目录</p>
<p></p>
<p> Private sName As String 注释:用于存储应用程序名</p>
<p></p>
<p> Private Sub Form_Load()</p>
<p></p>
<p> Dim s As String</p>
<p></p>
<p> 注释:从应用程序的命令行参数中取得数据</p>
<p></p>
<p> s = Trim(Command())</p>
<p></p>
<p> Dim p As Integer</p>
<p></p>
<p> p = InStr(1, s, ",")</p>
<p></p>
<p> If p > 0 Then</p>
<p></p>
<p> 注释:取得储服务器上的共享目录</p>
<p></p>
<p> sPath = Mid(s, 1, p - 1)</p>
<p></p>
<p> 注释:取得应用程序名</p>
<p></p>
<p> sName = Mid(s, p + 1, Len(s) - p)</p>
<p></p>
<p> 注释:定时器延时6秒,保证本地旧版应用程序退出运行</p>
<p></p>
<p> Timer1.Interval = 6000</p>
<p></p>
<p> Else</p>
<p></p>
<p> 注释:参数错误则退出</p>
<p></p>
<p> MsgBox "Error", vbCritical, ""</p>
<p></p>
<p> Unload Me</p>
<p></p>
<p> End</p>
<p></p>
<p> End If</p>
<p></p>
<p> End Sub</p>
<p></p>
<p></p>
<p> 注释:定时器代码</p>
<p></p>
<p> rivate Sub Timer1_Timer()</p>
<p></p>
<p> imer1.Interval = 0</p>
<p></p>
<p> Dim s1 As String</p>
<p></p>
<p> 取得应用程序的本地路径</p>
<p></p>
<p> If Len(App.Path) > 3 Then</p>
<p></p>
<p> s1 = App.Path + "\" + sName</p>
<p></p>
<p> lse</p>
<p></p>
<p> s1 = App.Path + sName</p>
<p></p>
<p> End If</p>
<p></p>
<p> 保证服务器关机或者路径错误仍可运行旧版本</p>
<p></p>
<p> On Error Resume Next</p>
<p></p>
<p> 注释:将服务器共享目录中的最新版本复制到本地</p>
<p></p>
<p> FileCopy sPath + sName, s1</p>
<p></p>
<p> Dim a As Long</p>
<p></p>
<p> 注释:执行本地的应用程序</p>
<p></p>
<p> a = Shell(s1, vbNormalFocus)</p>
<p></p>
<p> 注释:中介程序退出运行,应用程序自动更新结束</p>
<p></p>
<p> Unload Form1</p>
<p></p>
<p> End</p>
<p></p>
<p> End Sub</p>
<p></p>
<p> 将工程 FastCopy 编译为FastCopy.exe 并存储于服务器的共享目录。</p>
<p></p>
<p></p>
<p> 测试:</p>
<p></p>
<p> 1、 将服务器共享目录中的:MyApp.exe 复制到本地硬盘的某个目录中;</p>
<p></p>
<p> 2、 重新编译MyApp工程,将MyApp.exe复制到服务器的共享目录中,注意一定不要覆盖本地的MyExe.app ;</p>
<p></p>
<p> 3、 这样服务器上MyApp.exe 的修改时间肯定大于本地MyApp.exe的修改时间;</p>
<p></p>
<p> 4、 运行本地MyApp.exe ,几秒钟后屏幕上会出现"应用程序正在更新"的窗体,随后更新后应用程序再次被运行。则自动更新成功。</p>
<p></p>
<p> 5、 程序的修改时间可通过在文件上用鼠标按右键的属性或内容的菜单观察。</p>
<p></p>
<p> 本程序在Windows 98 和 VB 6.0 ,NT局域网络下测试通过。 </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -