VB實現應用程序在局域網上自動更新
我們在用VB開發大型應用程序時遇到如下問題,進入調試、維護階段開發小組進駐用戶單位,軟件交用戶試用會經常修改程序并重新編譯。然后再由程序員給用戶復制更新,或者通知用戶自行復制更新。對于少量用戶可以做到及時更新。而我們的一個用戶在一座十層的大廈中辦公,有十幾個部門(即有管理部門又有生產車間分布在不同的樓層),每個部門少則有2'3臺工作站,多則有數十臺工作站,與四臺服務器組成局域網絡.且每個部門應用程序各不相同,應用程序修改編譯后經常不能同步更新,從而造成部門內數據或者部門間的數據不一致。程序員每天都要跑上跑下檢查版本更新程序浪費了很多寶貴時間,即使通知部門主管自行更新,某些工作站也會出現遺漏現象。鑒于以上問題我們考慮使用程序自動更新技術,即自動檢查新版本,將新版本復制到本地,重新執行本地應用程序。
基本原理:在某個服務器上共享出一個目錄,其權限為程序員完全控制,其它用戶只讀。
例如:\NtServer01Refresh,程序員重新編譯后的應用程序.EXE都存放在此目錄下。
在應用程序的入口處調用版本檢查及更新過程,如果服務器應用程序的修改時間大于本地應用程序的修改時間,則認為有新版本出現,應該將服務器上的新版本復制到本地硬盤。
由于應用程序在運行時不能被新版本覆蓋,所以就需要中介程序FastCopy.EXE(也用VB編寫)來完成更新版本并重新運行本地應用程序。為了達到及時更新的目的可在應用程序中每隔5分鐘或10分鐘檢查一次是否有新版本。(此部分略有興趣的讀者可自行編程添加)
本例中:
服務器:NtServer01 共享目錄: Refresh
應用程序:MyApp.exe 中介程序:FastCopy.exe (都存儲于共享目錄中)
具體程序實現如下:
在應用程序工程MyApp中的部分代碼如下:
Option Explicit
'編譯后的應用程序名稱,注意沒有后綴 .EXE,本例為MYAPP
Private Const App_Name = "MyApp"
'最新的應用程序存放的路徑,本例為:服務器 NtServer01 共享目錄 Refresh
Private Const ExePath = "\NtServer01Refresh"
'中介程序名稱,注意沒有后綴 .EXE,本例為 FastCopy
Private Const MidExeName = "FastCopy"
'應用程序入口
Private Sub Form_Load()
If UCase(Trim(App.EXEName)) <> UCase(Trim(App_Name)) Then
MsgBox "必須將訂單管理系統的名稱更改為: " + App_Name
End
End If
'判斷是否有最新版本的應用程序,如有則自動更新
Call ExeRefresh
'下面為訂單管理系統的正常操作 略 ... ....
End Sub
'版本檢查及更新過程
rivate Sub ExeRefresh()
'定義四個臨時字符串變量
Dim s1 As String
Dim s2 As String
Dim s3 As String
Dim s4 As String
On Error Resume Next
'將本地應用程序MyApp.EXE的全路徑名存入 s1
'將本地中介程序FastCopy.exe的全路徑名存入 s3
s1 = "TNT"
If Len(App.Path) > 3 Then
s1 = App.Path + "" + Trim(App_Name) + ".exe"
s3 = App.Path + "" + MidExeName + ".EXE"
Else
s1 = App.Path + Trim(App_Name) + ".exe"
s3 = App.Path + MidExeName + ".EXE"
End If
s4 = "TNT"
'將本地應用程序MyApp.EXE文件的修改時間存入 s4
s4 = FileDateTime(s1)
s2 = "TNT"
'將網絡上應用程序MyApp.EXE文件的修改時間存入 s2
s2 = FileDateTime(ExePath + App_Name + ".EXE")
If s2 = "TNT" Then
MsgBox "沒有找到最新的可執行文件:" + ExePath + App_Name + ".EXE" _ + vbCrLf + vbCrLf + "原因1:存放最新EXE的服務器或者工作站沒有打開;" _ + vbCrLf + "原因2:存放最新EXE的路徑錯誤或者EXE文件不存在;" _+ vbCrLf + "請將此情況通知程序員." + vbCrLf + vbCrLf _+ vbCrLf + "按確定按鈕后,將繼續運行本地EXE文件.", vbCritical, "提示"
End If
If s2 = "TNT" Or s4 = "TNT" Then Exit Sub
'如果網絡上應用程序MyApp.EXE文件的修改時間,大于本地MyApp.EXE文件的修改時間
'然后再運行本地MyApp.EXE ,中介程序退出后,整個更新過程結束.
If CDate(s2) > CDate(s4) Then
'將網絡上的中介程序FastCopy.exe復制到本地,這樣可防止本地無中介程序時無法進行更新
FileCopy ExePath + MidExeName + ".EXE", s3
'則運行中介程序FastCopy.exe ,將最新的MyApp.EXE 復制到本地
s1 = Shell(s3 + " " + ExePath + "," + App_Name + ".EXE", vbNormalFocus)
'本地應用程序MyApp.EXE 終止運行,否則已經更新的MyApp.EXE無法覆蓋本地的MyApp.EXE .
End
End If
End Sub
將以上程序編譯為:MyApp.exe 存儲在共享目錄中.
在中介程序工程 FastCopy 中的代碼如下:
向工程中增加一個窗體Form1 ,向Form1中添加一個定時器 Timer1 , 增加一個標簽控件 Label1 ,其 Caption 為 "應用程序正在更新",并調整窗體大小.
Option Explicit
Private sPath As String '用于存儲服務器上的共享目錄
Private sName As String '用于存儲應用程序名
Private Sub Form_Load()
Dim s As String
'從應用程序的命令行參數中取得數據
s = Trim(Command())
Dim p As Integer
p = InStr(1, s, ",")
If p > 0 Then
'取得儲服務器上的共享目錄
sPath = Mid(s, 1, p - 1)
'取得應用程序名
sName = Mid(s, p + 1, Len(s) - p)
'定時器延時6秒,保證本地舊版應用程序退出運行
Timer1.Interval = 6000
Else
'參數錯誤則退出
MsgBox "Error", vbCritical, ""
Unload Me
End
End If
End Sub
'定時器代碼
rivate Sub Timer1_Timer()
imer1.Interval = 0
Dim s1 As String
取得應用程序的本地路徑
If Len(App.Path) > 3 Then
s1 = App.Path + "" + sName
lse
s1 = App.Path + sName
End If
保證服務器關機或者路徑錯誤仍可運行舊版本
On Error Resume Next
'將服務器共享目錄中的最新版本復制到本地
FileCopy sPath + sName, s1
Dim a As Long
'執行本地的應用程序
a = Shell(s1, vbNormalFocus)
'中介程序退出運行,應用程序自動更新結束
Unload Form1
End
End Sub
將工程 FastCopy 編譯為FastCopy.exe 并存儲于服務器的共享目錄。
測試:
1、 將服務器共享目錄中的:MyApp.exe 復制到本地硬盤的某個目錄中;
2、 重新編譯MyApp工程,將MyApp.exe復制到服務器的共享目錄中,注意一定不要覆蓋本地的MyExe.app ;
3、 這樣服務器上MyApp.exe 的修改時間肯定大于本地MyApp.exe的修改時間;
4、 運行本地MyApp.exe ,幾秒鐘后屏幕上會出現"應用程序正在更新"的窗體,隨后更新后應用程序再次被運行。則自動更新成功。
5、 程序的修改時間可通過在文件上用鼠標按右鍵的屬性或內容的菜單觀察。
本程序在Windows 98 和 VB 6.0 ,NT局域網絡下測試通過。
本文內容也適用于其它語言參考。