//simpleMain 启动入口 import fsys.update.app; import fsys.update.dlMgr; import win.dlg.message; import process.file; import process; namespace fsys.update; class simpleMain { ctor(appName,updateUrl,saveDir,onStatusChanged,httpHeaders,removable){ { if(!appName){appName = "软件"; } var dlMgr = initDownloadManger(appName,updateUrl,saveDir,onStatusChanged,httpHeaders); if(!dlMgr){ error("参数错误!",2); } if(_STUDIO_INVOKED){ return; } if( _ARGV.updated ){ saveLastStatusInfo({ version = _ARGV.version:""; description = _ARGV.description:""; status = "complete"; }) return; } elseif( _ARGV.update ) { var oldmain = _ARGV.oldmain; if( oldmain ){ if( ..process.file.test(oldmain) ){ var msgDlg = ..win.dlg.message(); msgDlg.icon = '\uF059' msgDlg.iconColor = 0xD4883B; var form = msgDlg.create('正在更新' + appName + ',\n' + "请退出以下程序:" + oldmain + ', \n点「确定」强行关闭进程, 点「取消」退出更新.',true); form.setInterval( function(){ if( !..process.file.test(oldmain) ) form.endModal(true) },1000 ) if( form.doModal() ){ ..process.file.terminate(oldmain); } else { return true; } } } var updater,err = ..fsys.update.app( _ARGV.src, _ARGV.dst,false,false); if(!updater){ if(err){ var msgDlg = ..win.dlg.message(); msgDlg.err('更新' +appName + '遇到错误,\n' + err) } return true; } var msgDlg = ..win.dlg.message(..mainForm); var frmUpdater = msgDlg.create('正在更新' + appName + '到版本:\n ' + updater.updateInfo.version + '\n',,true); frmUpdater.progress.setProgressRange(1,100); updater.onError = function(err,filename){ frmUpdater.message.text = '更新' +appName + '遇到错误,\n' + err + '\n' + filename; } var totalFiles = 100; updater.onCopyBegin = function(total){ totalFiles = total; } updater.onCopyFile = function(path,count){ frmUpdater.message.text = '正在更新' + appName +'\n' + path; frmUpdater.progress.progressPercentage = count/totalFiles * 100; } updater.onCopyFailed = function(path){ frmUpdater.message.text = '更新' + appName + '遇到错误,\n' + err + '\n' + filename; return frmUpdater.valid; } updater.onProcessFailed = function(paths){ frmUpdater.show(false); var msgDlg = ..win.dlg.message(..mainForm); if( msgDlg.ask('正在更新' +appName + ',\n' + '请退出以下程序:\n' + paths[1] + ', \n点击确定强行关闭进程, 点击取消退出更新.') ){ ..process.file.terminate(paths[1]); frmUpdater.show(true); return true; } else { return false; } } updater.onEnd = function(path){ frmUpdater.close(); saveLastStatusInfo({ version = updater.updateInfo.version:""; description = updater.updateInfo.description:""; status = "updated" }) if(onStatusChanged){ if( false === onStatusChanged(updater.updateInfo.version,updater.updateInfo.description,"updated") ){ ..win.quitMessage(); return; } } var mainPath = _ARGV.main; import fsys.fileInfo; if(!fsys.fileInfo.same(_ARGV.main,_ARGV.oldmain)){ if(..io.exist(_ARGV.oldmain)){ mainPath = _ARGV.oldmain; ..fsys.copy(_ARGV.main,_ARGV.oldmain); ..fsys.delete(_ARGV.main); } } ..process.execute( mainPath ,{"/updated","/version",updater.updateInfo.version,"/description",updater.updateInfo.description} ); ..win.quitMessage(); } updater.apply(); ..win.loopMessage(); return true; } elseif(!_STUDIO_INVOKED) { if(!dlMgr){ error("fsys.update.simpleMain() 只能在 main.aardio 中调用一次!",2); return true; } //如果之前已下载新版本完成,启动自动更新,成功返回true if(dlMgr.startUpdate(10000)){ return true; } } return null; } }; } namespace simpleMain{ var lastStatusInfo; saveLastStatusInfo = function(statusInfo){ ..publish("fsys.update.simpleMain.onStatusChanged",statusInfo.version:"",statusInfo.description:"",statusInfo.status); lastStatusInfo = statusInfo; } onStatusChanged = function(onStatusChanged){ ..subscribe("fsys.update.simpleMain.onStatusChanged",onStatusChanged); if(lastStatusInfo){ ..publish("fsys.update.simpleMain.onStatusChanged", lastStatusInfo.version:"", lastStatusInfo.description:"", lastStatusInfo.status, ) } } getReadyStatusInfo = function(){ return lastStatusInfo[["status"]] = "ready" ? ..table.assign(,lastStatusInfo); } checkUpdate = function(startUpdate){ var dlMgr = initDownloadManger(); if(!dlMgr){ return ; } if(_STUDIO_INVOKED){ saveLastStatusInfo({ status="failed"; description="必须发布后才能使用自动更新功能!"; version=""; }); return; } if(startUpdate){ return dlMgr.startUpdate(); } else { dlMgr.prepareUpdate(); } } var downloading; initDownloadManger = function(appName,updateUrl,saveDir,onStatusChanged,httpHeaders){ if(downloading){ return; } if(!updateUrl){ error("必须在 main.aardio 中提前调用 fsys.update.simpleMain函数!",2) } var downloadManger = function(){ var dlMgr = ..fsys.update.dlMgr(updateUrl,saveDir); dlMgr.httpHeaders = httpHeaders; downloading = true; dlMgr.onConfirmDownload = function(isUpdated,appVersion,latestVersion,description){ dlMgr[["latestVersion"]] = latestVersion; dlMgr[["updateDescription"]] = description; if(!isUpdated){ saveLastStatusInfo( { version = latestVersion; description = description; status = "latest"; } ) if(onStatusChanged){ onStatusChanged(latestVersion,description,"latest"); } downloading = false; } return isUpdated; } dlMgr.onEnd = function(updater,saveDir,appDir,mainPath){ if(updater){ if(onStatusChanged){ onStatusChanged(dlMgr[["latestVersion"]]:"",dlMgr[["updateDescription"]]:"","ready"); } saveLastStatusInfo( { version = dlMgr[["latestVersion"]]; description = dlMgr[["updateDescription"]]; status = "ready"; } ) } downloading = false; }; dlMgr.onError = function(err,filename){ err = ..string.concat("更新遇到错误:",err,'\r\n文件:',filename); saveLastStatusInfo( { version = dlMgr[["latestVersion"]]; description = err; status = "failed"; } ) if(onStatusChanged){ onStatusChanged(dlMgr[["latestVersion"]]:"",err,"failed" ); } ..io.stderr.write("更新遇到错误:",err,filename,'\n'); downloading = false; } return dlMgr; } //通过 fsys.update.simpleMain.checkUpdate() 调用 initDownloadManger = function(appName,updateUrl){ if(updateUrl){ error("fsys.update.simpleMain() 只能且必须在 main.aardio 中带参数调用一次!",3);} return downloadManger(); } return downloadManger(); } } /**intellisense() fsys.update.simpleMain = 自动更新启动程序简化版,\n更新程序与软件主程序合并到同一个程序中,\n必须在 main.aardio 中调用此构造函数,\n如果此函数返回true则必须退出程序,且不应显示任何其他窗口,\n fsys.update.simpleMain(appName,updateUrl,downloadDir,onStatusChanged,httpHeaders,removable) = @import fsys.update.simpleMain;\nif( fsys.update.simpleMain(\n "__/*软件产品名称*/",\n "http:",\n "/download/update-files",\n function(version,description,status){\n /*回调函数参数与 fsys.update.simpleMain.onStatusChanged 的回调函数参数相同*/;\n })){\n return 0; \n} fsys.update.simpleMain.onStatusChanged(订阅回调函数) = @.onStatusChanged(function(version,description,status){\n /*注意此回调可捕获到调用前或调用后的更新状态变更*/\n if(status=="ready"){\n __/*新版本已下载完成,更新已准备就绪\nversion参数为新版本号,description为更新说明*/\n }\n elseif(status=="updated"){\n /*已更新到新版本并准备启动新版,可使用_ARGV.oldmain获得更新之前的主程序路径,_ARGV.main取得更新后主程序路径*/\n }\n elseif(status=="complete"){\n /*当前已启动新版本主程序*/\n }\n elseif(status=="latest"){\n /*当前已经是新版本*/\n } \n}) fsys.update.simpleMain.checkUpdate(.(startUpdate) = 检查更新,\n参数@startUpdate指定下载新版后是否启动更新程序,\n调用此函数之前必须在main.aardio中提前调用过fsys.update.simpleMain函数。 fsys.update.simpleMain.getReadyStatusInfo() = 如果当前已下载好新版并准备更新就绪,\n返回statusInfo对象,包含version,description,status等属性。 end intellisense**/ /**intellisense(fsysUpdateSimpleStatusInfo) version = 新版本号 description = 版本信息 end intellisense**/