a=主程序
b=升级辅助程序如果只有一个账户的会话ID,逻辑好办.
a启动后将升级的文件准备到旗下目录,复制旗下目录的b到本目录或直接运行本目录的b,b强制结束运行中的相关的EXE,并复制旗下目录文件到本目录,完成后运行a的EXE,最后b自升结束如果有多个账户的会话ID,并且比如userx这个账户同时被windows多次使用,而且都有在运行a这个程序...
这逻辑就变的好复杂比如电脑上登陆了
adm的账号,会话id=0
userxx的账号2次,会话id是1和3
admin的账号,会话id=2,但没启动a
每个会话都有在启动a程序....
VB可以用这个API得到相应的会话ID,默认会话ID是0的.如果使用了终端,就会有多个会话IDPrivate Declare Function ProcessIdToSessionId Lib "kernel32" _
(ByVal dwProcessId As Long, _
ByRef pSessionId As Long) As Long
如何完美升级?
b=升级辅助程序如果只有一个账户的会话ID,逻辑好办.
a启动后将升级的文件准备到旗下目录,复制旗下目录的b到本目录或直接运行本目录的b,b强制结束运行中的相关的EXE,并复制旗下目录文件到本目录,完成后运行a的EXE,最后b自升结束如果有多个账户的会话ID,并且比如userx这个账户同时被windows多次使用,而且都有在运行a这个程序...
这逻辑就变的好复杂比如电脑上登陆了
adm的账号,会话id=0
userxx的账号2次,会话id是1和3
admin的账号,会话id=2,但没启动a
每个会话都有在启动a程序....
VB可以用这个API得到相应的会话ID,默认会话ID是0的.如果使用了终端,就会有多个会话IDPrivate Declare Function ProcessIdToSessionId Lib "kernel32" _
(ByVal dwProcessId As Long, _
ByRef pSessionId As Long) As Long
如何完美升级?
使用中的文件,是不被删除或复盖的.
而且还要考虑这同一个账号,不同会话ID如何再启动a
当然....从技术角度来说,也可以直接从服务器下达"自杀"指令,让各个本机客户端退出...但这样用户体验极差.四,所有用户关闭程序后,服务器会得知这个状态,并通知升级程序"所有本机客户端已退出,可以升级",升级程序就可以进行更新了.
a0
a
sa1
a
sa2
a
s
a1的a登陆后,收到升级信息,检查是否有升级标记upedt=最后修改时间和现在是否超过30分钟.如果超过则重新开始.
升级使用:(update,st=dfs;upuid=a1,upsdt=开始时间;upedt=最后修改时间),没有就标记a1,并下载(避免其它a重复下载)
a1的a下载完后,标记升级文件已准备好(update,st=cfss;upuid=a1).所有s结束自身
a1的a等待2秒后,检查升级文件中是否有adms的新文件.如果有就复制,
a1的a改变参数update,st=cafs;upuid=a1并启动s并结束自己;其它a收到后cafs后,启动s同时结束a
a1的s启动后,检测到st=cafs不要再启动a;当a1检测到upuid=a1时,进行所有文件的复制.
a1的a复制完文件后,改变参数st="",upuid="".其它程序再检测到时,各自启动各自的a
用ProcessIdToSessionId那个API,可以得到当前会话ID.当前运行的账号名用
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
即可获得.我之前想过由windows的service进程来控制,比如WINDOWS的服务里只有一项服务.只要各终端登陆一次,就启动一次.....但要找那些更底层的API,更困难....我也想过如果从会话1账号adm的终端,直接帮会话2账号admin的终端运行指定的程序(即由adm的身份帮助admin的身份启动程序)...超难~~~只要用双a,s端互启动的笨方法了.没办法保证服务器到底会有多少端被登陆中....一但被登陆中,运行中的文件又是不可被复制的......只好采用a和s的交互操作方法..
但这样用户体验极差:
程序都在后台运行的,不要在前台打扰用户就可以了.
看了不少升级方式....有时候,感觉强制升级还是必须的.
我们没办法保证上一个版本一点问题都没有,只能保证这次升级会更好.