| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4014 人关注过本帖, 1 人收藏
标题:用VFP编制的应用程序如何实现程序自动升级。
只看楼主 加入收藏
yanling48
Rank: 2
等 级:论坛游民
威 望:1
帖 子:31
专家分:43
注 册:2017-8-23
结帖率:100%
收藏(1)
已结贴  问题点数:20 回复次数:9 
用VFP编制的应用程序如何实现程序自动升级。
在开发和使用C/S工作方式的程序时,经常会遇到程序升级的问题,以前经常是用人工方式拷贝升级,这在网络变得日益庞大时显得十分烦琐。能不能像许多网络程序一样,在程序更新时自动更新本地程序呢?
搜索更多相关主题的帖子: VFP 应用程序 自动 升级 网络 
2017-08-28 10:45
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:10539
专家分:42927
注 册:2014-5-20
收藏
得分:8 
这样可否:
本地程序,运行时先检测有无新版本,有则运行外部的更新程序,关闭本地程序。
更新程序,运行时先下载新版本的本地程序,下载完运行本地程序,关闭更新程序。

收到的鲜花
  • yanling482017-08-29 14:45 送鲜花  3朵   附言:我很赞同
2017-08-28 11:00
yanling48
Rank: 2
等 级:论坛游民
威 望:1
帖 子:31
专家分:43
注 册:2017-8-23
收藏
得分:0 
回复 2楼 吹水佬
  在网上搜到一段代码,编译后没反应(需要修改的地方已按自己的修改了)。只是我是用win共享搭建的服务端,没有ftp服务器,请问是这个影响的吗?



    #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.  &&存放升级文件的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
2017-08-28 11:33
厨师王德榜
Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18
等 级:贵宾
威 望:199
帖 子:987
专家分:4946
注 册:2013-2-16
收藏
得分:12 
这个以前做过,说一下大致思路,
首先,在服务器端需要两个表,
A表,可以查询最新版本(参考字段:版本号(主键) ,更新时间(日期时间型)) ,
B表,用Memo型字段,装入二进制编码的最新的版本程序。以上是服务器端需要做的事情。

客户端,主执行文件和Load文件一定要分开,即两个Exe文件,要保证用户先运行Load文件,Load文件装入内存后,做以下事情:
1、检测与服务器连接是否正常?若无法连接,给出揭示,若正常连接,取服务器商版本表中的最新版本号;其次,获取本地主执行文件本身的版本号(用API或VFP本身提供了一个函数 AGETFILEVERSION( ) ,用哪个随意) ,得到本地主执行文件版本后,与服务器商的最新版本对比,如果本身版本号小于服务器端取回的版本号,则弹出对话框,揭示用户升级。
至于升级的过程,倒是简单,直接从服务器的B表中取出二进制编码,写到本地文件中(不要用主执行文件的名字,先另取名字)写成功后,可删除原来的主执行文件,把下载的文件改名为主执行文件,否则弹出对话框,告之用户升级失败,。最后,是移交控制权,Load程序退出,把主执行文件装入内存。真正实现业务逻辑的,是主执行程序,而Load程序不负责业务逻辑。
至于如何移交控制权,有多种方法,有用 wscript.shell 的,也有 通过Declare  ... Shell32.dll ,再ShellExecute()的,也有更简单的,直接在VFP中 用run的,自己查一下资料。更复杂的一点的,还需要在Load程序和主执行程序之间传参的,这个就不深入讲了。

收到的鲜花
  • yanling482017-08-29 14:42 送鲜花  3朵   附言:我很赞同
2017-08-28 11:34
yanling48
Rank: 2
等 级:论坛游民
威 望:1
帖 子:31
专家分:43
注 册:2017-8-23
收藏
得分:0 
回复 4楼 厨师王德榜
谢谢你,我是个业余的,你的方法太专业了,有很多我做起来都很费力。但是我用你提示的AGETFILEVERSION( )函数检测应用程序版本号,然后编了个更新用的EXE。如果有新的版本,先删除本地计算机的应用程序,然后用copy file 命令从服务端把新版的复制到本地计算机,从而实现自动更新。现在问题已解决。谢谢!
2017-08-28 17:11
yanling48
Rank: 2
等 级:论坛游民
威 望:1
帖 子:31
专家分:43
注 册:2017-8-23
收藏
得分:0 
分享下我的自动更新代码,菜鸟制作,大神莫笑!分享一下,只为互相交流。

****号处改成自己的文件名或目录。
第一,用VFP制作编译一个更新用的应用软件update.exe
  新建一个表单,controlbox属性.f. ,添加一个命令按钮command1和一个标签Label1。
   Label1的caption属性为:” 发现新版本,请更新!”
   command1的caption 属性为:”更新”
   command1的click事件为:

if file("./****.exe")=.f. &&判断文件是否存在
  COPY FILE "//****/****.exe" TO "./****.exe"   &&如果文件不存在,直接从服务端复制文件到本地计算机。
   =MESSAGEBOX("升级成功!请退出升级程序。",64,"提示")
   thisform.label1.caption="已是最新版本,请关闭升级程序!"
    this.caption="关闭"
else
  if this.caption="更新"
    DIMENSION aFiles1[1]
    DIMENSION aFiles2[1]
    AGETFILEVERSION(aFiles1," //****/****.exe ")&&检查服务端的软件版本号
    AGETFILEVERSION(aFiles2,". /****.exe ")&&检查本地计算机当前目录的软件版本号
    if  aFiles1[11]>aFiles2[11]   &&判断文件是否为最新版本
       delete file "./****.exe "  &&如果文件不是最新版本,删除老版本文件
       COPY FILE "//****/****.exe" TO "./****.exe" &&从服务端复制文件到本地计算机
        =MESSAGEBOX("升级成功!请退出升级程序。",64,"提示")
        thisform.label1.caption="已是最新版本,请关闭升级程序!"
        this.caption="关闭"
    else
        =MESSAGEBOX("已是最新版本。",64,"提示")
    endif
   else
    quit
   endif
endif

第二,在你的主程序中加入下列代码。
….
….
DIMENSION aFiles11[1]
DIMENSION aFiles21[1]
AGETFILEVERSION(aFiles11,"//****/****.exe")  &&检查服务端的软件版本号
AGETFILEVERSION(aFiles21,"./****. exe ")     &&检查本地计算机当前目录的软件版本号
if  aFiles11[11]>aFiles21[11]   &&如果存在新版本,执行更新程序(update.exe)
    DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER , STRING , STRING , STRING , STRING ,INTEGER
    = SHELLEXECUTE(0,0,'update.exe',0,0,1)
    quit
else
….          &&执行自己的应用程序
….
Endif

第三,在自己的项目中添加应用程序update.exe,编译生成应用程序。试用OK!

注意:update.exe要和自己的应用程序在同一目录下。如果第一次更新时,本地应用程序被删除,当新的文件未复制成功,可以直接运行update.exe更新一次来达到修复目的。
2017-08-29 14:19
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
收藏
得分:0 
学习了,咱也在琢磨这事。
2017-09-01 20:51
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
收藏
得分:0 
不知道升级后,客户原有的各种数据是否还在?
2017-09-01 20:53
yanling48
Rank: 2
等 级:论坛游民
威 望:1
帖 子:31
专家分:43
注 册:2017-8-23
收藏
得分:0 
回复 8楼 su0527
只是更新了应用软件,不修改数据库,升级对客户数据没任何影响。只是升级后,你可以实现新的功能或者修复原来的BUG。但是对于要升级数据库的不能用这个,比如增加字段等,需要单独编个程序升级,不可以采取简单复制数据库。那样做就会清空客户的数据了。
2017-09-02 17:59
wabc327
Rank: 1
等 级:新手上路
帖 子:60
专家分:0
注 册:2021-2-4
收藏
得分:0 
回复 6楼 yanling48
if  aFiles1[11]>aFiles2[11]   &&判断文件是否为最新版本    为什么运行到这一句时,下标超届,什么原因啊!
2021-02-08 18:26
快速回复:用VFP编制的应用程序如何实现程序自动升级。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019852 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved