之前写了一篇blog 是关于如何从网上下载PubFig数据库的,下载的时候才发现,由于网速非常的卡,导致下载的速度非常的慢,我开着机器下了一天一夜也就下了不到1w张图,看着还有6w的图片,我感觉到一阵的凉意,这时候我就想起了之前的一个下载的利器,迅雷想用迅雷来帮忙加速一下。
搜索了网上的资料,C#调用迅雷的方法有两种,一种利用com接口来调用,感觉上就是用程序操作了一下下载下来的迅雷的软件,具体的介绍参见http://www.veryhuo.com/a/view/40885.html
我在里面添加了我下载的迅雷的组件也成功的开启了下载的进程,但是非常遗憾的是,每次下载之前都会跳出一个对话框,要我来点一下确定,这样才能进行下载,这样显得非常的不方便。而且我使用的vip版的迅雷,好像也没有办法把这个框去掉,所以只好放弃了这个方法。
另外的方法就是调用迅雷提供的API接口,这个接口包含的是头文件,dll 和lib 适合的C和C++的调用,C#是不能直接添加的。找了好久才知道要用DLLImport来处理这个问题。
首先新建一个类来载入我们要用的DLL文件
class Thunder_SDK
{
enum enumTaskStatus
{
enumTaskStatus_Connect = 0, // 已经建立连接
enumTaskStatus_Download = 2, // 开始下载
enumTaskStatus_Pause = 10, // 暂停
enumTaskStatus_Success = 11, // 成功下载
enumTaskStatus_Fail = 12, // 下载失败
};
public const int XL_SUCCESS = 0;
public const int XL_ERROR_FAIL = 0x10000000;
// 尚未进行初始化
public const int XL_ERROR_UNINITAILIZE = XL_ERROR_FAIL + 1;
// 不支持的协议,目前只支持HTTP
public const int XL_ERROR_UNSPORTED_PROTOCOL = XL_ERROR_FAIL + 2;
// 初始化托盘图标失败
public const int XL_ERROR_INIT_TASK_TRAY_ICON_FAIL = XL_ERROR_FAIL + 3;
// 添加托盘图标失败
public const int XL_ERROR_ADD_TASK_TRAY_ICON_FAIL = XL_ERROR_FAIL + 4;
// 指针为空
public const int XL_ERROR_POINTER_IS_NULL = XL_ERROR_FAIL + 5;
// 字符串是空串
public const int XL_ERROR_STRING_IS_EMPTY = XL_ERROR_FAIL + 6;
// 传入的路径没有包含文件名
public const int XL_ERROR_PATH_DONT_INCLUDE_FILENAME = XL_ERROR_FAIL + 7;
// 创建目录失败
public const int XL_ERROR_CREATE_DIRECTORY_FAIL = XL_ERROR_FAIL + 8;
// 内存不足
public const int XL_ERROR_MEMORY_ISNT_ENOUGH = XL_ERROR_FAIL + 9;
// 参数不合法
public const int XL_ERROR_INVALID_ARG = XL_ERROR_FAIL + 10;
// 任务不存在
public const int XL_ERROR_TASK_DONT_EXIST = XL_ERROR_FAIL + 11;
// 文件名不合法
public const int XL_ERROR_FILE_NAME_INVALID = XL_ERROR_FAIL + 12;
// 没有实现
public const int XL_ERROR_NOTIMPL = XL_ERROR_FAIL + 13;
// 已经创建的任务数达到最大任务数,无法继续创建任务
public const int XL_ERROR_TASKNUM_EXCEED_MAXNUM = XL_ERROR_FAIL + 14;
// 任务类型未知
public const int XL_ERROR_INVALID_TASK_TYPE = XL_ERROR_FAIL + 15;
// 文件已经存在
public const int XL_ERROR_FILE_ALREADY_EXIST = XL_ERROR_FAIL + 16;
// 文件不存在
public const int XL_ERROR_FILE_DONT_EXIST = XL_ERROR_FAIL + 17;
// 读取cfg文件失败
public const int XL_ERROR_READ_CFG_FILE_FAIL = XL_ERROR_FAIL + 18;
// 写入cfg文件失败
public const int XL_ERROR_WRITE_CFG_FILE_FAIL = XL_ERROR_FAIL + 19;
// 无法继续任务,可能是不支持断点续传,也有可能是任务已经失败
// 通过查询任务状态,确定错误原因。
public const int XL_ERROR_CANNOT_CONTINUE_TASK = XL_ERROR_FAIL + 20;
// 无法暂停任务,可能是不支持断点续传,也有可能是任务已经失败
// 通过查询任务状态,确定错误原因。
public const int XL_ERROR_CANNOT_PAUSE_TASK = XL_ERROR_FAIL + 21;
// 缓冲区太小
public const int XL_ERROR_BUFFER_TOO_SMALL = XL_ERROR_FAIL + 22;
// 调用XLInitDownloadEngine的线程,在调用XLUninitDownloadEngine之前已经结束。
// 初始化下载引擎线程,在调用XLUninitDownloadEngine之前,必须保持执行状态。
public const int XL_ERROR_INIT_THREAD_EXIT_TOO_EARLY = XL_ERROR_FAIL + 23;
[DllImport("XLDownload.dll", EntryPoint = "XLInitDownloadEngine")]
public static extern bool XLInitDownloadEngine();
[DllImport("XLDownload.dll", EntryPoint = "XLURLDownloadToFile", CharSet = CharSet.Unicode)]
[DllImport("XLDownload.dll")] public static extern void XLStopTask(Int32 lTaskId); [DllImport("XLDownload.dll")]
public static extern bool XLUninitDownloadEngine();
}
参照给出的.h文件f仿照去一批可以调用的函数名。
完成了这一步之后,我们就可以对于迅雷的APIDLL 进行调用了。
仿照 给出的demo代码,我们用下面的方式进行调用。
<pre name="code" class="csharp"><span style="white-space:pre"> </span>Thunder_SDK.XLInitDownloadEngine();/./ initial the Engine
<span style="white-space:pre"> </span>Int32 dwRet = Thunder_SDK.XLURLDownloadToFile(ImgSavePath, parts[2], "", ref lTaskId);// creat the task
<span style="white-space:pre"> </span>do
{
Thread.Sleep(500);
last += 0.5F;
Int64 ullFileSize = 0;
Int64 ullRecvSize = 0;
int lStatus = -1;
dwRet = Thunder_SDK.XLQueryTaskInfo(lTaskId, ref lStatus, ref ullFileSize, ref ullRecvSize);
if (Thunder_SDK.XL_SUCCESS == dwRet)
{
// 输出进度信息
if (0 != ullFileSize)
{
double douProgress = (double)ullRecvSize / (double)ullFileSize;
}
else
{
<span style="white-space:pre"> </span> // 此时文件大小为0
}
if (last > 5 && 0 == ullFileSize)
{
lStatus = 12;// nofile return failed
}
if (11 == lStatus)
{
MessageBox.Show(string.Format("Download successfully.\n"));
break;
}
if (12 == lStatus)
{
MessageBox.Show(string.Format("Download failed.\n"));
StreamWriter m_StreamWriter = new StreamWriter(".\\dev_urls_failed.txt", true);
m_StreamWriter.Write(temp_line);
m_StreamWriter.Write("\n");
m_StreamWriter.Close();// 保留失败的urls
break;
}
label2.Text = string.Format("Last {0} Sec!", last);
}
} while (Thunder_SDK.XL_SUCCESS == dwRet);
Thunder_SDK.XLStopTask(lTaskId);//搜索程序
<span style="white-space:pre"> </span>Thunder_SDK.XLUninitDownloadEngine();
其中核心的函数是
Thunder_SDK.XLURLDownloadToFile(ImgSavePath, parts[2], "", ref lTaskId);
第一个参数是要保存的路径,第二个参数是URLs 第三个参数是参考路径,可以设置为空,第四个返回的是taskid 用来进行查询。
Thunder_SDK.XLQueryTaskInfo(lTaskId, ref lStatus, ref ullFileSize, ref ullRecvSize);
这个是查询函数,用来返回当前的状态 lStatus 和文件大小UllFileSize 和 下载的文件大小 UllRecvSizes.
两者配合使用就可以完成对于图片的下载。
这边有几个小问题要注意:
1 迅雷提供的dll是32位的,所以,64位的机器要设置成32位编译才没问题。
2 开始了一个task之后一定要stop掉这样,才不会造成程序的阻塞。
在迅雷的帮助下,半天就可以完成1w多张图片的下载,大大加快了我的速度,这样真好。