调用迅雷的接口,封装一个自己的类。
工程下载地址: http://pan.baidu.com/share/link?shareid=208860&uk=3037189616
迅雷下载库的网址:http://thunderplatform.xunlei.com
// FileName: Download.h #pragma once #include "lib\XLDownload.h" #include "lib\XLError.h" #include <vector> // 下载队列的大小,决定同时开启下载线程的数量 const int LIMIT = 2; struct Down { // 解析出来的下载地址 CString strDownURL; // 保存的路径 CString strSavePath; }; struct Flag { DWORD dwFlag; // 记录下载线程实时状态 LONG lTaskId; // 记录对应任务ID号 ULONGLONG ullFileSize; // 下载文件大小 ULONGLONG ullRecvSize; // 已下载大小 }; class CDownload { private: // 保存下载的日志信息 std::vector<CString> strLogArr; // 解析XML文件 //void Analysis (LPCTSTR lpPathXML, LPCTSTR lpBegin, LPCTSTR lpEnd); void Analysis (LPCTSTR lpPathXML); // 开始下载 void Start (void); // 调用迅雷的下载接口 void CreateDownThread (int n); // 下载任务查询监控线程 static void DownQury (LPVOID ptr); // 保存日志 void SaveLog (LPCTSTR lpPathAndName); public: // 保存解析出来的下载队列 std::vector<Down> strDownArr; // 记录最新的下载位置 int m_nIndex; // 下载队列的大小,对应位为1时,该下载位为空,可以启动新的下载线程 struct Flag Flags[LIMIT]; // 总共的下载数 int m_nTotal; // 失败的下载数 int m_nFail; // 成功的下载数 int m_nSuccess; CDownload(); ~CDownload(); BOOL DownloadFilesByXML(LPCTSTR lpPahtXML); };
// FileName: Download.cpp #include "stdafx.h" #include "Download.h" #include <Shlwapi.h> #include <locale.h> #pragma comment(lib, "lib\\XLDownload.lib") // 包含XTP界面库头文件 #include "XTToolkitPro.h" CDownload::CDownload() { // 初始化 m_nIndex = 0; // 初始化为没有下载线程 for (int n=0; n<LIMIT; n++) { Flags[n].dwFlag = 1; Flags[n].lTaskId = n; } m_nSuccess = 0; m_nTotal = 0; m_nFail = 0; } CDownload::~CDownload() { } BOOL CDownload::DownloadFilesByXML(LPCTSTR lpPathXML) { DWORD dwRet = XL_SUCCESS; // 检测XML文件是否存在 if (!PathFileExists(lpPathXML)) { ::MessageBox(NULL, _T("XML文件不存在!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION); return FALSE; } // 解析XML文件 Analysis(lpPathXML); // 统计下载链接数 m_nTotal = strDownArr.size(); // 开始下载 Start(); return TRUE; } //void CDownload::Analysis(LPCTSTR lpPathXML, LPCTSTR lpBegin, LPCTSTR lpEnd) void CDownload::Analysis(LPCTSTR lpPathXML) { // 读取XML文件 CXTPPropExchangeXMLNode px(TRUE, NULL, _T("DownLoadInfo")); if (!px.LoadFromFile(lpPathXML)) { ::MessageBox(NULL, _T("打开XML文件出错!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION); return; } if (!px.OnBeforeExchange()) { ::MessageBox(NULL, _T("OnBeforeExchange false!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION); return; } px.SetCompactMode(TRUE); CXTPPropExchangeEnumeratorPtr enumItem(px.GetEnumerator(_T("Item"))); POSITION posItem = enumItem->GetPosition(); CString strLocalName; Down down; // 遍历所有的结点 while (posItem) { CXTPPropExchangeSection sec(enumItem->GetNext(posItem)); if (sec->IsLoading()) { PX_String(sec->GetSection(_T("URL")), NULL, down.strDownURL); PX_String(sec->GetSection(_T("LocalPath")), NULL, down.strSavePath); PX_String(sec->GetSection(_T("LocalName")), NULL, strLocalName); down.strSavePath += strLocalName; // 路径转换 down.strSavePath.Replace('/', '\\'); strDownArr.push_back(down); } } } // 下载任务查询 void CDownload::DownQury (LPVOID ptr) { CDownload* pDown = (CDownload*)ptr; bool nSign = true; DWORD dwRst; TCHAR errorBuf[500]; DWORD dwSize = 500; CString strLog; // 如果没有下载完成一直下载 while ((pDown->m_nIndex < (pDown->strDownArr).size()) || nSign) { int n = 0; LONG temp = -1; nSign = false; while (n<LIMIT) { switch(pDown->Flags[n].dwFlag) { // 没有下载,开始新的下载 case 1 : pDown->CreateDownThread(n); dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize)); if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size()) { pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); pDown->strLogArr.push_back(_T("state:suceess")); pDown->Flags[n].dwFlag = temp; } else { if (pDown->m_nIndex < pDown->strDownArr.size()) { pDown->m_nFail += 1; XLGetErrorMsg(dwRst, errorBuf, dwSize); pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); strLog.Format(_T("state:%s"), errorBuf); pDown->strLogArr.push_back(strLog); } pDown->m_nIndex += 1; } break; // 成功下载完, 开始新的下载 case 11: pDown->CreateDownThread(n); dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize)); if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size()) { pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); pDown->strLogArr.push_back(_T("state:suceess")); pDown->Flags[n].dwFlag = temp; } else { if (pDown->m_nIndex < pDown->strDownArr.size()) { pDown->m_nFail += 1; XLGetErrorMsg(dwRst, errorBuf, dwSize); pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); strLog.Format(_T("state:%s"), errorBuf); pDown->strLogArr.push_back(strLog); } pDown->m_nIndex += 1; } break; // 下载失败,开始新的下载 case 12: pDown->CreateDownThread(n); dwRst = XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize)); if (dwRst == XL_SUCCESS && pDown->m_nIndex<pDown->strDownArr.size()) { pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); pDown->strLogArr.push_back(_T("state:suceess")); pDown->Flags[n].dwFlag = temp; } else { if (pDown->m_nIndex < pDown->strDownArr.size()) { pDown->m_nFail += 1; XLGetErrorMsg(dwRst, errorBuf, dwSize); pDown->strLogArr.push_back(pDown->strDownArr[pDown->m_nIndex].strDownURL); strLog.Format(_T("state:%s"), errorBuf); pDown->strLogArr.push_back(strLog); } pDown->m_nIndex += 1; } break; // 默认处理 default: XLQueryTaskInfo(pDown->Flags[n].lTaskId, &temp, &(pDown->Flags[n].ullFileSize), &(pDown->Flags[n].ullRecvSize)); pDown->Flags[n].dwFlag = temp; if (temp == enumTaskStatus_Download) { nSign = true; } } n++; } //Sleep(1); } // 保存日志 pDown->SaveLog(_T("C:\\down.log")); CString strTemp; strTemp.Format(_T("下载完成! 下载总数:%d 成功总数%d 失败总数%d 日志存在位置:C:\\down.log"), pDown->m_nTotal, pDown->m_nSuccess, pDown->m_nFail); ::MessageBox(NULL, strTemp, _T("友情提示"), MB_OK); pDown->m_nSuccess = 0; pDown->m_nTotal = 0; pDown->m_nFail = 0; // 恢复初始状态 pDown->m_nIndex = 0; // 恢复为下载队列为空 for (int n=0; n<LIMIT; n++) { pDown->Flags[n].dwFlag = 1; pDown->Flags[n].lTaskId = n; // 无论是否下载成功,都必须调用XLStopTask XLStopTask(pDown->Flags[n].lTaskId); } //释放资源 XLUninitDownloadEngine(); } void CDownload::Start (void) { int nIndex = 0; // 1、初始化下载引擎 if ( FALSE == XLInitDownloadEngine() ) { ::MessageBox(NULL, _T("初始化下载引擎失败!"), _T("友情提示"), MB_OK|MB_ICONEXCLAMATION); return; } // 下载任务查询监控线程 ::CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)DownQury, this, 0, NULL); } // 调用迅雷的下载接口 void CDownload::CreateDownThread (int n) { DWORD dwRst = 0; if (m_nIndex < strDownArr.size()) { dwRst = XLURLDownloadToFile(strDownArr[m_nIndex].strSavePath, strDownArr[m_nIndex].strDownURL, NULL, Flags[n].lTaskId); if (dwRst == XL_SUCCESS) { Flags[n].dwFlag = enumTaskStatus_Download; m_nIndex++; m_nSuccess++; } } else { m_nIndex = strDownArr.size(); } } void CDownload::SaveLog (LPCTSTR lpPathAndName) { CStdioFile file; std::vector<CString>::iterator iter; // 保存现在的语言环境 char * old_locale = _strdup(setlocale(LC_CTYPE,NULL)); // 设置中文环境 setlocale(LC_CTYPE, "chs"); if (file.Open(lpPathAndName, CFile::modeCreate|CFile::modeWrite)) { for (iter=strLogArr.begin(); iter!=strLogArr.end(); iter++) { file.WriteString(*iter); file.WriteString(_T("\n")); } } file.Close(); // 还原语言区域的设置 setlocale(LC_CTYPE, old_locale); // 释放内存 free(old_locale); }