标题:升级程序与当前程序切换时有点问题,请教一下?
只看楼主
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
结帖率:96.03%
已结贴  问题点数:20 回复次数:10 
升级程序与当前程序切换时有点问题,请教一下?
升级原理:首先,下载升级程序(update.exe)到当前程序(小精灵.exe)所在目录,这一步很正常,具体方法略去。
在小精灵 主窗口的unload事件中代码如下:
SET SAFETY OFF
IF FILE("update.exe")=.t. AND FILE("小精灵.exe")=.t.   &&如果发现升级程序 update.exe,则在退出时启动另外一个可执行程序sprite.exe
    DECLARE INTEGER ShellExecute IN shell32.DLL INTEGER , STRING , STRING , STRING , STRING ,INTEGER
    = SHELLEXECUTE(0,0,'upsprite\sprite.exe',0,0,1)  &&启动另一个程序sprite.exe
ENDIF
quit
CLEAR EVENTS

在sprite.exe 的主程序中代码如下:  &&启用该程序的目标是,删除原程序并将升级程序重命名为原程序
_screen.visible=.f.
SET TALK OFF
SET SAFETY OFF
SET CENTURY ON
SET DATE YMD
SET HOURS TO 24
SET DEFAULT TO SYS(5)+SYS(2003)  &&全路径
lj2=alltrim(LEFT(SYS(5)+SYS(2003),RAT("\",SYS(5)+SYS(2003),1)-1))
DELETE FILE ("&lj2.\小精灵\小精灵.exe")                 &&删除原程序
RENAME &lj2.\小精灵\update.exe TO &lj2.\小精灵\小精灵.exe       &&将升级程序重命名为原程序
QUIT

问题:多数电脑上可以正常运行,有的不行。初步分析,sprite.exe主程序中,删除原程序和重命名操作,有时发生在原程序unload代码中的quit之前发生,有时发生的quit之后发生。前者是会报错的,因为小精灵正在占用中。

问题2:我在 DELETE FILE ("&lj2.\小精灵\小精灵.exe") 前加 inkey(3),意思是等待原程序彻底退出再向下操作,能解决上述问题。但如果退出后,快速地再次启动程序,又会出问题。

请问,如何改进代码?
搜索更多相关主题的帖子: 升级 update exe 精灵 SET 
2018-03-07 07:32
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
虽然执行了QUIT,windows对这个进程的事务处理还未完成,进程还没结束。
windows系统有时也不太稳定,进程挂死的现象时有发生。
可否换另一思路,程序启动时首先进行更新处理过程,这样可能会稳定些。
再夸张点,先检测和中止进程,然后再更新。
2018-03-07 08:13
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:649
专家分:2156
注 册:2014-2-7
得分:0 
我你可试一下如下方法:
1. 设计一个升级程序 update.exe,用于更新本地应用程序 app.exe

2.在app.exe的主程序main.prg的开头,加入如下代码:

* 假设以版本号来判断是否升级
cVerOld = 1.00 && 旧版本号
cVerNew = 1.02 && 新版本号
IF cVerNew # cVerOld
    RUN /N update.exe
    QUIT
ENDIF

泉城飞狐
2018-03-07 08:32
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
得分:0 
回复 2楼 吹水佬
启动程序时如何更新,能否指导的详细些。
2018-03-07 19:12
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
得分:0 
回复 3楼 liuxingang28
发现新版本,则运行新版本。那原版本如何处理,新版本名子如何修改。如果不修改新程序名字,那下次又如何再升级?
2018-03-07 19:15
su0527
Rank: 2
等 级:论坛游民
帖 子:452
专家分:79
注 册:2015-1-10
得分:0 
回复 2楼 吹水佬
测试某一指定的进程是否存在,如果存在,就关闭。这怎么能做到?能否给代码,急需要解程序升级更新这个问题?
2018-03-07 23:07
zyxxzhyg
Rank: 3Rank: 3
来 自:江西
等 级:论坛游侠
威 望:5
帖 子:58
专家分:134
注 册:2014-6-26
得分:0 
cCaption="定时器"
Declare integer FindWindow in win32api string cClass,String cCaption
if FindWindow(0,cCaption)#0
=messagebox("此程序已经运行,请查看任务栏!",16,"系统资源省着点用哦! ^_^ ")
return .f.
endif
这是我以前试过的确保只能运行一次程序,改下应该能用吧
2018-03-08 08:36
童生
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:205
专家分:455
注 册:2018-3-7
得分:0 
回复 7楼 zyxxzhyg
VFP没有互拆变量这个概念吗?
2018-03-08 08:56
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:649
专家分:2156
注 册:2014-2-7
得分:0 
回复 4楼 su0527
1. 升级的意思当然是用新版本覆盖旧版本的同名文件,也就是说在update.exe中用新版本的app.exe替换原来的app.exe,同时也要将配置文件(install.ini)更新。
2. 关于版本号:可以在本地文件夹和服务器文件夹下分别建立一个文本文件,如:install.ini,在文本文件中可添加一行如:Ver=1.02,在运行update.exe时,可提取和对比两个版本号以判定是否需要升级。
也可以不采用版本号,直接对比本地和升级路径上的主程序(如:app.exe)的文件大小和日期时间,如果二者不相同,则启动升级过程。
3. 只要将服务器更新路径下的install.ini中的版本号修改一下,如:将Ver=1.02,修改为Ver=1.03,则下次启动本地程序时可自动启动升级过程。切记,升级过程也需要覆盖本地的install.ini,以便同步版本号。

[此贴子已经被作者于2018-3-8 10:04编辑过]


泉城飞狐
2018-03-08 09:58
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:20 
以下是引用su0527在2018-3-7 23:07:25的发言:

测试某一指定的进程是否存在,如果存在,就关闭。这怎么能做到?能否给代码,急需要解程序升级更新这个问题?

试试处理挂起情况:
新建文件夹.rar (35.69 KB)


*********************
** test.exe
*********************
ASTACKINFO(a程序)
SET DEFAULT TO ADDBS(JUSTPATH(a程序[2]))     

DECLARE LONG GetWindowThreadProcessId IN user32 LONG, LONG@

IF FILE("test - 副本.exe")  &&用一个副本测试
    LOCAL PID, oApp
    PID = 0
    GetWindowThreadProcessId(_VFP.hWnd, @PID)
    oApp = CREATEOBJECT("Shell.Application")
    oApp.ShellExecute("update.exe", TRANSFORM(PID), "", "open", 1)
    MESSAGEBOX("更新test.exe,PID: "+TRANSFORM(PID)) && 挂起测试
ELSE
    MESSAGEBOX("运行test.exe")
ENDIF
CLEAR ALL

*********************
** update.exe
*********************
LPARAMETERS PID
SET SAFETY OFF

#DEFINE STILL_ACTIVE    0x00000103
#DEFINE PROCESS_ALL_ACCESS    0x001F0FFF

DECLARE LONG OpenProcess IN Kernel32 LONG, LONG, LONG
DECLARE LONG CloseHandle IN Kernel32 LONG
DECLARE LONG GetExitCodeProcess IN Kernel32 LONG, LONG@
DECLARE LONG TerminateProcess IN Kernel32 LONG, LONG

LOCAL hProcess, nExitCode, bl
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, INT(VAL(PID)))
nExitCode = 0
GetExitCodeProcess(hProcess, @nExitCode)
bl = nExitCode != STILL_ACTIVE
IF !bl
    bl = TerminateProcess(hProcess, 0) != 0
    INKEY(0.1)
ENDIF
IF bl
    TRY
        COPY FILE "test - 副本.exe" TO test.exe &&用一个副本测试
        DELETE FILE "test - 副本.exe"
        MESSAGEBOX("更新成功")
    CATCH
        MESSAGEBOX("更新失败")
    ENDTRY
ELSE
    MESSAGEBOX("更新失败")
ENDIF
CloseHandle(hProcess)
CLEAR ALL
2018-03-08 11:45



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-485058-1-1.html




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

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