返回列表 发帖

控制台下载工具pget.exe

本帖最后由 happy886rr 于 2017-4-21 21:40 编辑
控制台下载工具pget,支持IP显示、彩显、通配符、断电续传、下载进度、速度、剩余时间提示等功能。假如我要下载的网址,某个地方不确定,用通配符(*)替代就行 http://www.a.com/(*).zip。
(图片为外链)
将该图存为a.zip,解压即可得到1.2版的二进制文件和所有源码,仅13KB大小,运行迅捷。

用法:
-----------------------------------------------------------------
pget -u[url] -n[number range] -r[root directory]
-----------------------------------------------------------------
     -h Show help information
     -u Set the download url
     -n Set the number range of the url
     -r Set the download root directory
-----------------------------------------------------------------COPY
举例:
REM 单文件下载,使用-u开关指定下载地址
pget -uhttp://ddd2.pc6.com/soft12/VC6.0green.rar
REM 通配符下载,使用-n开关指定统配符范围
pget -u http://img1.mm131.com/pic/1008/(*).jpg -n 1-10
REM 用-r开关指定文件保存目录
pget -u http://img1.mm131.com/pic/1008/(*).jpg -n 1-10 -r ".\test"COPY
pget最新1.3版源码,加入了对ftp、百度网盘超长链接下载的支持,1.3版仅做源码更新,不再提供新的二进制文件,且源码支持VC6.0直接编译。
/*
THE BATCH DOWNLOAD TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.3
PGET.EXE
-----------------------------------------------------------------
               _
   _       _ _(_)_     |  The Batch Download Tool with colorful ,
  (_)     | (_) (_)    |  Copyright@2017~2019 By Happy, Pget.Exe
   _ _   _| |_  __ _   |  Type "-h" for help.
  | | | | | | |/ _` |  |  
  | | |_| | | | (_| |  |  Version 1.3 (2017-04-21 21:28 UTC)
_/ |\__'_|_|_|\__'_|  |  Official http://www.bathome.net/thread
|__/                   |  -43879-1-1.html
-----------------------------------------------------------------
                      :;vLxLc;,                  
                  ,JZMMBBBMBMBMBJi.               
                LRBMMRMRRDWZZKRMBMBDs            
              rBMBWDDDKKPE00XZPHEGORRMu           
            .ZBRODOG0XZZGZGKZKPaEHGEEKRD         
           ,OBOROGZGZE0DZEZZ0ZPDKXZWK0SEE         
          .EBORWGZDZKKDEGKGGEPWGZZWEZaEJB;        
          UBRRDDGRWOOMRREOOOKOEGXKHWKPP2ZH        
         7BRWGOGBMBMBMBBBMBMBRORWPPEO0ZPRO        
         RMOEWOBRPr;:,:ruxc3x7DBMBOMRRGWMX        
        ;MMEOOBP.  :SRBU:     ,iDOBBRRWWB:        
        vBMGWBG.     .;ii:. .::::raGRRGBE         
        :MBZMBJ         .,..;;PMOL,2BBBD.         
         UMRRBx  . ..,.,.. ,:..,::7BMBZ.         
          MRMMM ...:;..,;,:;:..  ,BMBK.           
          0BMBR;...::;::;;;;,,..sBBB7            
         :BRBi,i7:.  .:;r;:...;OBOJ               
        ;BMBr ::i7;,.......sF                     
    LGBBBMBMF:;,:;777i;;:1BMBRr                  
  iBMBMBMMRBO7::.:ic7c77;aBBMBBBMBMBEZv:,:.      
:BMZFHWMORRMOr...:icvvr;:KMBRRDOOODRWD1cr7:.     
SRuis0MRRRRRREL,..,::::,:EMORRMOROOuu1i:. :::.   
;3Ba7aBRZGBROMBWF: .....:;0ZRRMMBMBMB7::7L:  .;rL;
;;SOZBMOJ,3BRRBBMRc..,.,,:2RRMOMF7rXJ;;7LZOMi.....
7:;0BSMWx; 7RRRRBMBD:.,,,:DEMRWWMPL,:iL;ir1BBJ:.  
:. sBxsMM3; :MOBMBDBG:.,.;UaBMOWMBM0:;v1uSvLLLrri:
J;. KWsLBMU:aMBMBMcLGx...:7JBMMWMU2H  .,rKR0J;;;r;
JL7  .  iBDRMBMBO: .7x,..,;7MBMBRU 1J:       ....
siJ7.:s1RMBRPcr:     ,:,::;.iRBMBMUGBMBOs:    . .
:;rJUcJsrLL.           :;r,  .rZMMMBK0DBMBMu.   .
..7vJur7ir:  ::.        :.     :s;:r1L: .7BMBB3:  
. :vs3rx;L. ...,        .,      .i:  .:.:r;;;DMBBM
, .,727;,,.,:....                 ,::...3JLr   .JG
. .,;U7;..:i;::;,..  .             :ir:rxu1v.     
: ,.:xJ:..:;7iL3i.;:  ...      ..   :;1JLL07, ..,.
: . .;v7ir:;;rvcr::7                 7ciLSU7.
*/
#include   <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include <windows.h>
#include  <direct.h>
#include    <time.h>
#include    <math.h>
#include      <io.h>
#pragma comment(lib, "Ws2_32.lib")
/*************宏量定义*************/
#define SAFE_SIZE  1024
#define FILE_EXIST 0
//定义帮助说明
#define HELP_INFORMATION "\
-----------------------------------------------------------------\n\
pget -u[url] -n[number range] -r[root directory]\n\
-----------------------------------------------------------------\n\
     -h Show help information\n\
     -u Set the download url\n\
     -n Set the number range of the url\n\
     -r Set the download root directory\n\
-----------------------------------------------------------------\n\
version 1.3\n"
#define STR_HEAD "\
-------------Welcome you to use the pget download tool-----------"
#define STR_LINE "\
-----------------------------------------------------------------"
/*************类型定义*************/
typedef HRESULT (WINAPI *PGETA)(LPUNKNOWN,LPCSTR,LPCSTR,DWORD,LPBINDSTATUSCALLBACK);
/*************全局变量*************/
static int M, N, Z;
static char murl[SAFE_SIZE], mpath[SAFE_SIZE]=".\\";
static char proGRESS[64]={0};
int OPTIND=1, OPTOPT;
char* OPTARG;
clock_t preTime;
ULONG preProgress;
HANDLE handle_out;
/*************进度回调*************/
class DownloadProgress :public IBindStatusCallback
{
public:
HRESULT __stdcall QueryInterface(const IID &, void **) {
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef(void) {
return 1;
}
ULONG STDMETHODCALLTYPE Release(void) {
return 1;
}
HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding *pib) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetPriority(LONG *pnPriority) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnLowResource(DWORD reserved) {
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult, LPCWSTR szError) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD *grfBINDF, BINDINFO *pbindinfo) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) {
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID riid, IUnknown *punk) {
return E_NOTIMPL;
}
virtual HRESULT __stdcall OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText){
if (ulProgressMax != 0){
//进度百分数
int downloadSpeed, restTime;
int i=(int)ulProgress * 100.0 / (int)ulProgressMax;
int j=i/2, disTime=(int)(clock()-preTime);
if(disTime > 100){
downloadSpeed=((int)ulProgress-(int)preProgress) * CLOCKS_PER_SEC / disTime / 1000;
restTime=(downloadSpeed!=0) ?((int)ulProgressMax-(int)ulProgress) / downloadSpeed :99999;
preProgress=ulProgress, preTime+=disTime;
}else if(i <100){
return S_OK;
}
if(i==100){
downloadSpeed=restTime=0;
}
for(int n=1; n<=j; n++){
proGRESS[n]='=';
}
//显示进度百分比
fprintf(stdout, "\r%s%3d%% %3dKB/s,%3dm%02ds ", proGRESS, i, downloadSpeed, restTime/1000/60, restTime/1000%60);
fflush(stdout);
}
return S_OK;
}
};
/*************功能函数*************/
//彩显函数
int ColorString(HANDLE handle_out, char* pstrA, char* pstrB, int colorA, int colorB, int num)
{
SetConsoleTextAttribute(handle_out, colorA);  //项目色
fprintf(stdout, pstrA);
SetConsoleTextAttribute(handle_out, colorB);  //数据色
(num<0)?fprintf(stdout, pstrB):fprintf(stdout, "%d\n", num);
return 0;
}
//判断字母
BOOL isLetter(char* p)
{
return (p && (('A'<=*p&&*p<='Z')||('a'<=*p&&*p<='z'))&&(*(p+1)=='\0'))?TRUE:FALSE;
}
//子串查找/i版
char* strrstr(const char *dst, const char *src)  
{  
const char *pdst=dst, *psrc=src;
char *ret=NULL;  
while(*dst){
while(*pdst==*psrc){
if(*pdst=='\0'){
return ret=(char*)dst;
}else{  
pdst++;  
psrc++;  
}  
}  
if(*psrc=='\0'){ret=(char*)dst;}
pdst=++dst;  
psrc=src;  
}  
return ret;  
}
//域名IP解析
int URLDownloadToIP(HANDLE handle_out, const char* downloadURL)
{
WSADATA wsaData;  
WSAStartup(MAKEWORD(2,2), &wsaData);
char *pstr=(char*)downloadURL, *urlweb=(char*)calloc(SAFE_SIZE, sizeof(char)), *tstr=urlweb;
while(*pstr!=':'){pstr++;}
pstr+=3;
while(*pstr!='/'&& *pstr!='\n' && *pstr!='\0'){
*tstr++=*pstr++;
}
const char* pszUrl=(const char*)urlweb;
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
//fprintf(stdout, "Init socket faile\n");  
return 1;  
}
struct hostent *pHost = gethostbyname(pszUrl);
if (pHost == NULL) {  
WSACleanup();  
//fprintf(stdout, "pHost == NULL \n");  
return 1;  
}
//主机正式名称
ColorString(handle_out, "[URL-HOST] ", (pHost)?pHost->h_name:"NULL", 4|8, 1|2|8, -1);
fprintf(stdout, "\n");
//主机别名,可以有多个
int iIndex = 0;  
while(pHost->h_aliases[iIndex]) {
ColorString(handle_out, "[URLALIAS] ", pHost->h_aliases[iIndex], 4|8, 1|2|8, -1);
fprintf(stdout, "\n");
iIndex++;  
}
//地址字节数,IPV4是4,IPV6是6
if(pHost->h_length==4) {
ColorString(handle_out, "[IP-VTYPE] ", "IPV4\n", 4|8, 4|8, -1);
}
else if(pHost->h_length==6) {
ColorString(handle_out, "[IP-VTYPE] ", "IPV6\n", 4|8, 4|8, -1);
}
iIndex = 0;
while(pHost->h_addr_list[iIndex]) {
ColorString(handle_out, "[IP-ADDRE] ", inet_ntoa(*(struct in_addr*)pHost->h_addr_list[iIndex]), 4|8, 2|4|8, -1);
fprintf(stdout, "\n");
iIndex++;  
}   
WSACleanup();
//释放空间
free(urlweb);
return 0;
}
//开关解析
int GetOpt(int nargc, char *nargv[], char *ostr)
{
static char* place="";
static char* lastostr=(char *) 0;
register char* oli;
char* index();
if(ostr!=lastostr){
lastostr=ostr;
place="";
}
if(!*place){
if(
(OPTIND>=nargc)              ||
(*(place=nargv[OPTIND])!='-')||
(!*(++place))
){
place="";
return(EOF);
}
if (*place == '-' && place[1] == 0){
++OPTIND;
return(EOF);
}
}
if ((OPTOPT=(int)*place++)==(int)':' || !(oli=strchr(ostr, OPTOPT))){
if(!*place){++OPTIND;}
}
if (oli != NULL && *(++oli) != ':'){
OPTARG=NULL;
if(!*place){++OPTIND;}
}
else{
if(*place){
OPTARG=place;
}else if(nargc<=++OPTIND){
place="";
}else{
OPTARG=nargv[OPTIND];
}
place="";
++OPTIND;
}
return(OPTOPT);
}
/*************下载函数*************/
int URLGetToFile(void)
{
//装载DLL模块
HMODULE hLib=LoadLibraryW(L"URLMON");
if(hLib==NULL){
fprintf(stdout, "ERROR");
return 1;
}
//过小红伞本地查杀
PGETA PgetUrlToFileA=(PGETA)GetProcAddress(hLib, "URLDownloadToFileA");
//是否启用通配符
BOOL useMARK=FALSE;
//分配URL字串
char* aurl =(char*)calloc(SAFE_SIZE, sizeof(char));
char* durl =(char*)calloc(SAFE_SIZE, sizeof(char));
char* dest =(char*)calloc(SAFE_SIZE, sizeof(char));
char* pftr =(char*)calloc(       16, sizeof(char));
//定义URL指针
char *purl=NULL, *surl=NULL, *pdit=NULL;
//批量下载
for(int i=M; i<=N; i++){
    surl=murl, purl=aurl;
while(*surl !='\0'){
//替换正则标签
if(*surl=='(' && *(surl+1)=='*' && *(surl+2)==')'){
useMARK=TRUE;
if(Z >0){
sprintf(pftr, "%%0%dd", Z);
sprintf(dest, pftr, i);
}else if(Z==-1){
sprintf(dest, "%c",  (char)i);
}else{
sprintf(dest, "%d",  i);
}
pdit=dest;
while(*pdit !='\0'){
*(purl++)=*(pdit++);
}
surl+=3;
}else{
*(purl++)=*(surl++);
}
}
//置结束符
*purl='\0';
strcpy(durl, mpath);
strcat(durl, "\\");
strcat(durl, strrchr(aurl, '/')+1);
//截断特殊字符
purl=durl;
while(
*purl!='?' &&
*purl!='*' &&
*purl!='"' &&
*purl!='>' &&
*purl!='<' &&
*purl!='|' &&
*purl!='\0'
){purl++;}
*purl='\0';
//显示下载网址
ColorString(handle_out, "[*] ", aurl, 4|8, 1|2|8, -1);
fprintf(stdout, "\n");
//绘制进度框
ColorString(handle_out, "", (char*)proGRESS, 4|8, 2|4|8, -1);
//进度归零
memset(proGRESS, ' ', 51);
proGRESS[0]='[', proGRESS[51]=']';
preTime=clock();
preProgress=(ULONG)0;
//进度回调入口
DownloadProgress progress;
IBindStatusCallback* callback=(IBindStatusCallback*)&progress;
//调用API下载
if (PgetUrlToFileA(NULL, aurl, durl, 0, static_cast<IBindStatusCallback*>(&progress)) != S_OK){
fprintf(stdout, "ERROR");
}
//统一换行
fputs("\n\n", stdout);
if(useMARK==FALSE){
break;
}
}
//清理工作
free(aurl);
free(durl);
free(dest);
free(pftr);
return 0;
}
/*************MAIN函数*************/
int main(int argc, char** argv)
{
if(argc<2){
//无参数则退出
fprintf(stdout, HELP_INFORMATION);
exit(0);
}
int flag=0, K;
while((K=GetOpt(argc,argv,"hu:n:r:"))!=-1)
{
switch(K)
{
case 'h':
case 'H':
fprintf(stdout, HELP_INFORMATION);
exit(0);
case 'u':
case 'U':
if(OPTARG !=NULL){
strcpy(murl, OPTARG);
flag=1;
}
break;
case 'n':
case 'N':
if(OPTARG !=NULL){
char *snumsrc=strtok(OPTARG, " \t-"), *tmps=(snumsrc!=NULL)?strtok(NULL, " \t-"):NULL, *zp=snumsrc;
if(isLetter(snumsrc) && isLetter(tmps)){
int exnum1=*snumsrc, exnum2=*tmps;
Z=-1;
M=(exnum1 <= exnum2)?(N=exnum2, exnum1):(N=exnum1, exnum2);
}else if(tmps!=NULL){
if(*zp=='0'){
while('0'<= *zp && *zp <='9'){
Z++;
zp++;
}
}
M=atoi(snumsrc), N=atoi(tmps);
if(M>N){
int exnum=M;
M=N, N=exnum;
}
}
}
break;
case 'r':
case 'R':
if(OPTARG !=NULL){
strcpy(mpath, OPTARG);
}
break;
default:
fprintf(stdout, "Unknown switch '-%c'\n", K);
exit(1);
}
}
//判断是否有网址参数
if(flag==0){
fprintf(stdout, "Needs download url\n");
exit(1);
}
//判断网址是否超长
if(strlen(murl)>768){
fprintf(stdout, "Download url too long\n");
exit(1);
}
//判断网址是否有效
if(
(strrchr((const char*)murl, '/')==NULL) ||
(
(strrstr((const char*)murl, "http://" ) != murl) &&
(strrstr((const char*)murl, "https://") != murl) &&
(strrstr((const char*)murl, "ftp://"  ) != murl) &&
(strrstr((const char*)murl, "ftps://" ) != murl)
)
){
fprintf(stdout, "The url is error\n");
exit(1);
}
//下载目录不否存则创建
if(_access(mpath, FILE_EXIST)!=0){
_mkdir(mpath);
}
//无法创建下载目录退出
if(_access(mpath, FILE_EXIST)!=0){
fprintf(stdout, "Can not creat the download directory\n");
exit(1);
}
//获取控制台输出句柄
handle_out=GetStdHandle(STD_OUTPUT_HANDLE);
//获取控制台初始配色
WORD orgCOLOR;
CONSOLE_SCREEN_BUFFER_INFO buffINFO;
GetConsoleScreenBufferInfo(handle_out, &buffINFO);
orgCOLOR=buffINFO.wAttributes;
//显示目标网站IP
ColorString(handle_out, STR_HEAD, "\n", 4|8, 2|4|8, -1);
URLDownloadToIP(handle_out, murl);
ColorString(handle_out, STR_LINE, "\n", 4|8, 2|4|8, -1);
//调用下载函数
URLGetToFile();
//还原字体颜色
SetConsoleTextAttribute(handle_out, orgCOLOR);
return 0;
}COPY

本帖最后由 happy886rr 于 2017-4-21 13:45 编辑

回复 10# CrLf
好的,已过360免杀,模仿hash.c。

TOP

回复 9# happy886rr


    目前直接运行看到的提示最后一行是两行黏在一起的,建议下次更新时在 version 后补个 \n

TOP

本帖最后由 happy886rr 于 2017-4-20 20:50 编辑

回复 8# CrLf
MD版,只要安装了QQ,就带那个dll,所以直接MD版 。第一版getopt的开关也写错了,1.1版都做了修正。

TOP

卧槽,怎么编译到这么小的

TOP

回复 6# happy886rr


    是啊,一般连中文都会变成 UTF8的URL编制形式(%e4%b8%ad)
[url=][/url]

TOP

回复 5# CrLf
好的,不过url一般都是ascii码组成的,ansi C已经够用。

TOP

毕竟是在 windows 下使用,建议以后的作品考虑一下适配宽字符的情况

TOP

传一个备份,回头上传到 Batch-CN
已用 strip 和 upx 压缩体积,另,HELP_INFORMATION 的末尾应该有个 \n 才对

TOP

回复 2# freesoft00
理论上都支持,我刚测试过,支持https,代理自己写上ip端口试试。

TOP

这个是否支持https连接下载,是否支持设置代((理

TOP

返回列表