在VFP中实现程序自动升级
在开发和使用C/S工作方式的程序时,经常会遇到程序升级的问题,以前经常是用人工方式拷贝升级,这在网络变得日益庞大时显得十分烦琐。能不能像许多网络程序一样,在程序更新时自动更新本地程序呢?笔者经过两天时间,参考了一些资料,在VFP下实现了程序的自动升级功能。基本思路是通过升级程序自动从指定的FTP服务器中下载升级文件来更新程序。程序的基本运行环境:VFP7+Win98(Win2000),服务端:FTP服务器,程序运行正常。对于VFP5以上程序应该可以运行,但没有测试。在其他语言下实现方法应该是相同的。
第一步
判断程序是否需要升级。最简单的方法是在程序中设定一个版本常量,在程序启动时和远端库中设定的程序最新版本号进行比较。如果比远端库中的版本号旧,则执行升级程序。由于正在运行的程序是不能覆盖的,因此需要一个单独的升级程序来进行升级工作。假定此程序的名字是update.exe,也用VFP编译,则在主程序中须通过以下方法运行此升级程序:
DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER , STRING , STRING , STRING , STRING ,INTEGER
= SHELLEXECUTE(0,0,'update.exe',0,0,1)
同时用quit命令来退出主程序。
第二步
利用升级程序进行更新。主要升级的程序如下(在使用中需要根据实际情况修改以下程序中用中文说明的地方。为了美观和实际使用的方便,可以建立一个表单,来实现升级服务器的选择、用户名和密码的输入)。
#Define INTERNET_INVALID_PORT_NUMBER 0
#Define INTERNET_OPEN_TYPE_DIRECT 1
#Define INTERNET_OPEN_TYPE_PROXY 3
#Define INTERNET_DEFAULT_FTP_PORT 21
#Define INTERNET_FLAG_ASYNC 268435456 && &H10000000
#Define INTERNET_FLAG_FROM_CACHE 16777216 && &H1000000
#Define INTERNET_FLAG_OFFLINE 16777216
#Define INTERNET_FLAG_CACHE_IF_NET_FAIL 65536 && &H10000
#Define INTERNET_OPEN_TYPE_PRECONFIG 0
#Define FTP_TRANSFER_TYPE_ASCII 1
#Define FTP_TRANSFER_TYPE_BINARY 2
#Define INTERNET_SERVICE_FTP 1
#Define INTERNET_SERVICE_GOPHER 2
#Define INTERNET_SERVICE_HTTP 3
#Define FILE_ATTRIBUTE_NORMAL 128 && 0x00000080
Declare INTEGER InternetOpen IN wininet;
STRING sAgent, INTEGER lAccessType, STRING sProxyName,;
STRING sProxyBypass, STRING lFlags
Declare INTEGER InternetCloseHandle IN wininet INTEGER hInet
Declare INTEGER InternetConnect IN wininet;
INTEGER hInternetSession, STRING sServerName,;
INTEGER nServerPort, STRING sUsername,;
STRING sPassword, INTEGER lService,;
INTEGER lFlags, INTEGER lContext
Declare INTEGER FtpGetFile IN wininet;
INTEGER hFtpSession, STRING lpszRemoteFile,;
STRING lpszNewFile, INTEGER fFailIfExists,;
INTEGER dwFlagsAndAttributes,;
INTEGER dwFlags, INTEGER dwContext
sAgent = ""var1""
sProxyName = Chr(0)
sProxyBypass = Chr(0)
lFlags = 0
hOpen = InternetOpen (sAgent, INTERNET_OPEN_TYPE_DIRECT,;
sProxyName, sProxyBypass, lFlags)
If hOpen = 0
=MESSAGEBOX(""找不到库 WinInet.Dll 的入口"",16,"" 警告"")
Return
Endif
*在此修改自己的FTP服务器数据
strHost = ""ftp.abc.com"" &&存放升级文件的FTP服务器地址
strUser = ""user"" &&升级的FTP用户名
strPwd = ""1111"" &&FTP用户密码
hFtpSession = InternetConnect (hOpen, strHost,;
INTERNET_INVALID_PORT_NUMBER,;
strUser, strPwd,;
INTERNET_SERVICE_FTP, 0, 0)
If hFtpSession = 0
= InternetCloseHandle (hOpen)
=MESSAGEBOX(""找不到指定的服务器"",16,"" 警告"")
Return
Endif
*以下设置FTP的路径和文件名
lpszRemoteFile = ""/aaa.exe"" && FTP上的路径和文件名
lpszNewFile = ""./aaa.exe"" && 下载到本地的路径和文件名,默认在同一目录中
fFailIfExists = 0 && 如果此文件已经存在,直接进行覆盖,不提问
dwContext = 0
lnResult = FtpGetFile (hFtpSession, lpszRemoteFile, lpszNewFile,;
fFailIfExists, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_ASCII,;
dwContext)
= InternetCloseHandle (hFtpSession)
= InternetCloseHandle (hOpen)
If lnResult # 1
=MESSAGEBOX(""升级失败!请检查用户名和密码是否正确。"",16,"" 警告"")
ELSE
=MESSAGEBOX(""升级成功!请退出升级程序。"",64,"" 提示"")
thisform.Release &&升级成功可自动离开表单
Endif
Return
第三步
使用和调用升级程序相同的方法,运行主程序退出升级程序,完成程序的升级过程。