http://xldoc.xl7.xunlei.com/0000000026/index.html
以上是迅雷开放下载引擎的内容,以dll的形式提供给了我们几个接口方便我们黑箱作业,并且也提供了相应的demo来让我们使用。
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include ".\\XLDownload.h"
#include ".\\XLError.h"
int main()
{
// 1、初始化下载引擎
if ( FALSE == XLInitDownloadEngine() )
{
printf("Initialize download engine failed.\n");
return 1;
}
// 2、启动新任务
// PS:如果链接无法通过,请把工程属性“将wchar_t设置为内置类型 (/Zc:wchar_t)”设置为Yes
LONG lTaskId = 0;
DWORD dwRet = XLURLDownloadToFile(
_T("d:\\xmp.exe"),
_T("http://xmp.down.sandai.net/kankan/XMPSetup_3.8.1.485-www.exe"),
_T(""), lTaskId);
if ( XL_SUCCESS != dwRet )
{
XLUninitDownloadEngine();
printf("Create new task failed, error code:%d.\n", dwRet);
return 1;
}
printf("Begin download file.\n");
// 3、查询任务状态
do
{
::Sleep(1000);
ULONGLONG ullFileSize = 0;
ULONGLONG ullRecvSize = 0;
LONG lStatus = -1;
dwRet = XLQueryTaskInfo(lTaskId, &lStatus, &ullFileSize, &ullRecvSize);
if ( XL_SUCCESS==dwRet )
{
// 输出进度信息
if ( 0 != ullFileSize )
{
double douProgress = (double)ullRecvSize/(double)ullFileSize;
douProgress *= 100.0;
printf("Download progress:%.2f%%\n", douProgress);
}
else
{
printf("File size is zero.\n");
}
if ( enumTaskStatus_Success==lStatus )
{
printf("Download successfully.\n");
break;
}
if ( enumTaskStatus_Fail==lStatus )
{
printf("Download failed.\n");
break;
}
}
} while( XL_SUCCESS==dwRet );
// 4、无论是否下载成功,都必须调用XLStopTask
XLStopTask(lTaskId);
// 5、释放资源
XLUninitDownloadEngine();
return 0;
}
是一个简单的控制台程序,当然也提供了GUI的Demo(包含了下载进度条,暂停下载,继续下载,不用说,肯定是支持断点续传的),可以查找或者直接问我要都OK。
有一个被大家普通反感的问题或说诟病就是运行Demo的时候会在托盘中出现迅雷的下载图标,让人比较不爽吧。如果在我们自己的程序中出现这个。。。。。。。。。
所以如果能隐藏掉就比较理想了,也就涉及到了隐藏托盘图标,更准确一点的说是如何隐藏某个程序的托盘图标。
在CodeProject上看到一篇文章非常不错,这里分享一下:
http://www.codeproject.com/Articles/10807/Shell-Tray-Info-Arrange-your-system-tray-icons
简单来说,这个文章就是教我们如何来管理系统托盘图标的,比如调整位置啦,左右键单击双击啦等等。
网上教我们隐藏托盘图标的代码有很多,用不着我在这里啰嗦,简单说一个原理吧:
通过类名["Shell_TrayWnd" -> "TrayNotifyWnd" -> "SysPager" -> "ToolbarWindow32"]最终得到托盘窗口句柄 -> 通过发送 TB_BUTTONCOUNT消息得到托盘窗口TBBUTTON的个数 -> 通过得到总数,用For循环,向每个BUTTON发送TB_GETBUTTON消息 -> 用ReadProcessMemory读取每个TBBUTTON结构 -> 再通过TBBUTTON.dwData 得到TRAYDATA结构。顺便说一下TRAYDATA结构吧,可以在CodeProject那篇文章中看到,据说是微软没有公开的一个托盘结构。
struct TRAYDATA
{
HWND hwnd;
UINT uID;
UINT uCallbackMessage;
DWORD Reserved[2];
HICON hIcon;
};
只要得到这个结构,那么托盘的图标,就可以进行一系列自己想要的操作了,修改图标,隐藏图标,移动图标等。
例子:
#include<stdio.h>
#include<windows.h>
#include<tchar.h>
#include <atlbase.h>
#include <atlconv.h>
#include <CommCtrl.h>
#include "XLDownload.h"
#include "XLError.h"
#pragma comment(lib,"XLDownload.lib")
void ShowTrayIcon(TCHAR szIcon[],BOOL show);
void RaiseToDebugP();
int main()
{
RaiseToDebugP();
//1.初始化下载引擎
if(FALSE==XLInitDownloadEngine())
{
printf("Initialize download engine failed.\n");
return 1;
}
ShowTrayIcon(_T("迅雷下载开放引擎"),false);
//2.启动新任务
//PS:如果链接无法通过,请把工程属性"将wchar_t设置为内置类型 (/Zc:wchar_t)"设置为Yes
LONG lTaskId=0;
int dwRet=XLURLDownloadToFile(_T("d:\\xmp.exe"),_T("http://xmp.down.sandai.net/kankan/XMPSetup_3.8.1.485-www.exe"),_T(""),lTaskId);
ShowTrayIcon(_T("迅雷下载开放引擎"),false);
if(XL_SUCCESS!=dwRet)
{
XLUninitDownloadEngine();
printf("Create new task failed,error code:%d.\n",dwRet);
return 1;
}
printf("Begin download file.\n");
//3、查询任务状态
do
{
::Sleep(1000);
ULONGLONG ullFileSize=0;
ULONGLONG ullRecvSize=0;
LONG lStatus=-1;
dwRet=XLQueryTaskInfo(lTaskId,&lStatus,&ullFileSize,&ullRecvSize);
if(XL_SUCCESS==dwRet)
{
//输出进度信息
if(0!=ullFileSize)
{
double douProgress=(double)ullRecvSize/(double)ullFileSize;
douProgress*=100.0;
printf("Download progress:%.2f%%\n",douProgress);
}
else
{
printf("File Size is zero.\n");
}
if(enumTaskStatus_Success==lStatus)
{
printf("Download successfully.\n");
break;
}
if(enumTaskStatus_Fail==lStatus)
{
printf("Download failed.\n");
break;
}
}
}while(XL_SUCCESS==dwRet);
//4、无论是否下载成功,都必须调用XLStopTask
XLStopTask(lTaskId);
//5、释放资源
XLUninitDownloadEngine();
return 0;
}
void ShowTrayIcon(TCHAR szIcon[],BOOL show)
{
HWND hWnd,hWndPaper;
unsigned long lngPID;
long ret,lngButtons;
HANDLE hProcess;
LPVOID lngAddress;
long lngTextAdr,lngHwndAdr,lngHwnd,lngButtonID;
TCHAR strBuff[1024]={0};
TCHAR* str = NULL;
TCHAR *pp = NULL;
hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL);
hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);
if(!hWndPaper)
hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);
else
hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);
ret = GetWindowThreadProcessId(hWnd, &lngPID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS
|PROCESS_VM_OPERATION
|PROCESS_VM_READ
|PROCESS_VM_WRITE,
0,
lngPID);
lngAddress = VirtualAllocEx(hProcess,0, 0x4096, MEM_COMMIT, PAGE_READWRITE);
lngButtons = SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);
for(int i=0 ;i< lngButtons - 1;i++)
{
ret = SendMessage(hWnd,TB_GETBUTTON,i,LPARAM(lngAddress));
ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 16),&lngTextAdr,4,0);
if(lngTextAdr != -1)
{
ret = ReadProcessMemory(hProcess, LPVOID(lngTextAdr),strBuff,1024,0);
ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 12),&lngHwndAdr,4,0);
ret = ReadProcessMemory(hProcess, LPVOID(lngHwndAdr),&lngHwnd, 4,0);
ret = ReadProcessMemory(hProcess, LPVOID(long(lngAddress) + 4),&lngButtonID,4,0);
USES_CONVERSION;
str = OLE2T((LPOLESTR)(strBuff));
pp=_tcsstr(str,szIcon);
if(pp != NULL)
{
if(show)
{
SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,0);
}
else
{
SendMessage(hWnd,TB_HIDEBUTTON,lngButtonID,1);
}
}
}
}
VirtualFreeEx( hProcess, lngAddress, 0X4096, MEM_RELEASE);
CloseHandle(hProcess);
}
//提升权限函数
void RaiseToDebugP()
{
HANDLE hToken;
HANDLE hProcess = GetCurrentProcess();
if ( OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
{
TOKEN_PRIVILEGES tkp;
if ( LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid) )
{
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
BOOL bREt = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0) ;
}
CloseHandle(hToken);
}
}
以上代码在VS08中测试通过,如果您是VC6.0那么不需要用到提升权限函数,不对的地方还望指出,欢迎交流。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课