最近在研究软件的自动更新功能,手动更新太麻烦而且对电脑小白来说容易出错。之前对自动更新没什么概念,不知道如何实现。简单百度之后,原来“更新”功能是一个单独的模块,在需要更新的时候启动这个模块,然后将主程序的相关文件更新,以达成更新主程序功能的目的。那么,有两个问题:1.什么时候启动更新?2.如何更新主程序的相关文件?
我的思路是:在服务器某个位置放置一个文件,这个文件里存放了需要更新文件的列表以及一个类似版本号的标识。主程序每次启动的时候 如果是联网状态下,就去读取这个文件中的“版本标识”来和自身的版本标识比较,如果自身的版本标识低于站点的这个标识就启动更新程序,获取列表中所表明的需要更新的文件,存放到指定位置即可完成更新。那么如何获取这些文件呢?应该是要使用下载功能。
文件列表和版本号这个好实现,最不济弄个txt文件存储,然后解析一下就行。下载这个功能比较麻烦,C#的http命名空间里有下载功能的类,不太好用,虽然没怎么深入研究过。当然,我是小白一个,再怎么深入研究也玩不出什么花来,就想吃现成的。网上疯狂搜罗一番,发现迅雷云加速开放平台比较对我的胃口,就它了。不过可惜的是,正式的SDK申请已经在3年前暂停了,看样子也没有恢复申请的迹象。不过好在还有个试用版的SDK可以用,对付我这个小功能应该是绰绰有余了。好在我当时顺手把这个试用版的SDK保存下来了,不然我现在能悔死,因为现在整个下载页面都打不开了。
材料有了,怎么用又是个问题。接口代码全是C/C++,而我用的是C#!SDK压缩包里提供了一个更新日志txt文件、一个xldl.dll文件、一个xldl.h文件还有一个download文件夹。真正可以直接交互的就是xldl.dll动态链接库,xldl.h文件定义了需要用的的一些类型。居然没有示例文档!!!虽然我的水平烂到你把文档给我了我也未必能看懂,但是你不给我,那我就真是抓瞎了。网上兜兜转转找到一个“基础教程”压缩包,里面是个word文档,有一段完整的示例代码。如获至宝,赶紧下载下来。文档一个5页,代码占了3页,示例截图占1页,说明文字占1页。信息量忒少了点,不过好过没有。完整代码如下:
#include"stdafx.h" #include<Windows.h> #include<iostream> #include<stdio.h> #include<tchar.h> #include<tchar.h> #include<Shlwapi.h> #include"assert.h" #pragmacomment(lib,"shlwapi.lib") #include"xldl.h" voidDownloadFile(DownWrapper* pWapper,conststd::wstring&wstrUrl,conststd::wstring&wstrFilename,conststd::wstring&wstrSavePath); int_tmain(intargc, _TCHAR* argv[]) {
assert(argc>= 3); WCHARszModulePath[MAX_PATH] = {0}; ::GetModuleFileName(NULL, szModulePath, MAX_PATH); ::PathRemoveFileSpec(szModulePath); WCHARszDllpath[MAX_PATH] = {0}; ::PathCombine(szDllpath, szModulePath, L"xldl.dll"); //查找xldl.dll,并加载该dll 1 DownWrapper* pWapper = newDownWrapper(szDllpath); if (!pWapper->Init()) //初始化下载引擎 2 { std::cout<<"Error, Init Failed!"<<std::endl; return 1; } std::wstringwstrUrl(argv[1]); std::wstringwstrSavePath(argv[2]); std::wstringwstrFileName(argv[3]); DownloadFile(pWapper, wstrUrl, wstrFileName, wstrSavePath); Sleep(600000); pWapper->UnInit(); //卸载下载引擎 7 return 0; } voidDownloadFile( DownWrapper* pWapper,conststd::wstring&wstrUrl,conststd::wstring&wstrFilename,conststd::wstring&wstrSavePath) { //初始化新建任务参数 DownTaskParampara; memcpy(para.szTaskUrl, wstrUrl.c_str(), wstrUrl.length()*sizeof(WCHAR)); std::wstringwstrRefUrl = L""; memcpy(para.szRefUrl, wstrRefUrl.c_str(), wstrRefUrl.length()*sizeof(WCHAR)); memcpy(para.szFilename, wstrFilename.c_str(), wstrFilename.length()*sizeof(WCHAR)); memcpy(para.szSavePath, wstrSavePath.c_str(), wstrSavePath.length()*sizeof(WCHAR)); //新建任务 HANDLEhTask = pWapper->TaskCreate(para);//3 std::cout<<"Create New Task"<<std::endl; if (hTask) { std::cout<<"Now Start Task"<<std::endl; pWapper->TaskStart(hTask); //开始任务 4 } else { std::cout<<"Create Task Filed!"<<std::endl; return ; } DownTaskInfoinfo; while(true) {
Sleep(1000); pWapper->TaskQuery(hTask, info); //轮询任务信息 5 std::cout<<"Size: "<<info.nTotalSize<<", Percent: "<<info.fPercent<<", Speed: "<<info.nSpeed<<std::endl; if (info.stat == TSC_COMPLETE) { std::cout<<"Total File Size: " <<info.nTotalSize<<std::endl; std::cout<<"Task Success!"<<std::endl; break; } if (info.stat == TSC_ERROR) { std::cout<<"Task Failed!"<<std::endl; break; } } pWapper->TaskDelete(hTask); //删除任务,释放任务占用内存 6 }
原文链接:https://www.cnblogs.com/zhang-15-506/p/7800220.html
原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/7194