最近在研究軟件的自動更新功能,手動更新太麻煩並且對電腦小白來講容易出錯。以前對自動更新沒什麼概念,不知道如何實現。簡單百度以後,原來「更新」功能是一個單獨的模塊,在須要更新的時候啓動這個模塊,而後將主程序的相關文件更新,以達成更新主程序功能的目的。那麼,有兩個問題:1.何時啓動更新?2.如何更新主程序的相關文件?ios
個人思路是:在服務器某個位置放置一個文件,這個文件裏存放了須要更新文件的列表以及一個相似版本號的標識。主程序每次啓動的時候 若是是聯網狀態下,就去讀取這個文件中的「版本標識」來和自身的版本標識比較,若是自身的版本標識低於站點的這個標識就啓動更新程序,獲取列表中所代表的須要更新的文件,存放到指定位置便可完成更新。那麼如何獲取這些文件呢?應該是要使用下載功能。api
文件列表和版本號這個好實現,最不濟弄個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頁。信息量忒少了點,不過好過沒有。完整代碼以下:app
#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 }