简单粗暴的书写

使用WinHTTP实现文件下载,支持HTTPS。
支持保存文件路径,支持下载文件命名。
添加UrlEncode和UrlDecode(非标准规范,仅便于解析后获取文件名称)。
无暂停或继续下载
Usage: ProjectName.exe [Url] [drive:\path\filename]

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
#include <iostream>#pragma comment(lib, "winhttp.lib")//https://blog.csdn.net/c914620529/article/details/73503708
//ANSI对应char,UTF-8对应char类型,Unicode(UTF-16)对应wchar_t
//ANSI字符串的英文使用一个字节,中文使用两个字节
//Unicode字符串的英文与中文都使用两个字节
//UTF8字符串的英文使用一个字节,中文使用三个字节//ANSI-->Unicode
std::wstring StringToWString(const std::string& str)
{int num = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);wchar_t* wide = new wchar_t[num];MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wide, num);std::wstring wstr = wide;delete[] wide;return wstr;
}//Unicode-->ANSI
std::string WStringToString(const std::wstring& wszString)
{int num = WideCharToMultiByte(CP_ACP, 0, wszString.c_str(), -1, NULL, 0, NULL, NULL);char* wide = new char[num];WideCharToMultiByte(CP_ACP, 0, wszString.c_str(), -1, wide, num, NULL, NULL);std::string str = wide;delete[] wide;return str;
}//UTF8-->Unicode
std::wstring u8StringTouWString(const std::string& str)
{int num = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);wchar_t* wide = new wchar_t[num];MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wide, num);std::wstring uwstr = wide;delete[] wide;return uwstr;
}//Unicode-->UTF8
std::string uWStringTou8String(const std::wstring& wszString)
{int num = WideCharToMultiByte(CP_UTF8, 0, wszString.c_str(), -1, NULL, 0, NULL, NULL);char* wide = new char[num];WideCharToMultiByte(CP_UTF8, 0, wszString.c_str(), -1, wide, num, NULL, NULL);std::string str = wide;delete[] wide;return str;
}//via @Dewei
//修改UrlEncode部分
std::string urlencode(std::string& str_source)
{char const* in_str = str_source.c_str();int in_str_len = (int)strlen(in_str);int out_str_len = 0;std::string out_str;register unsigned char c;unsigned char* to, * start;unsigned char const* from, * end;unsigned char hexchars[] = "0123456789ABCDEF";from = (unsigned char*)in_str;end = (unsigned char*)in_str + strlen(in_str);start = to = (unsigned char*)malloc(3 * strlen(in_str) + 1);while (from < end) {c = *from++;if ((c < '0' && c != '-' && c != '.' && c != '/' && c != '%') ||(c < 'A' && c > '9' && c != ':') ||(c > 'Z' && c < 'a' && c != '_') ||(c > 'z')) {to[0] = '%';to[1] = hexchars[c >> 4];to[2] = hexchars[c & 15];to += 3;}else {*to++ = c;}}*to = 0;out_str_len = (int)(to - start);out_str = (char*)start;free(start);return out_str;
}//via @Dewei
static int php_htoi(char* s)
{int value;int c;c = ((unsigned char*)s)[0];if (isupper(c))c = tolower(c);value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;c = ((unsigned char*)s)[1];if (isupper(c))c = tolower(c);value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;return (value);
}
//via @Dewei
//修改UrlDecode部分
std::string urldecode(std::string& str_source)
{char const* in_str = str_source.c_str();int in_str_len = (int)strlen(in_str);int out_str_len = 0;std::string out_str;char* str;str = _strdup(in_str);char* dest = str;char* data = str;while (in_str_len--) {if (*data == '%' && in_str_len >= 2 && isxdigit((int)*(data + 1))&& isxdigit((int)*(data + 2))) {*dest = (char)php_htoi(data + 1);data += 2;in_str_len -= 2;}else {*dest = *data;}data++;dest++;}*dest = '\0';out_str_len = (int)(dest - str);out_str = str;free(str);return out_str;
}std::string GetFileName(std::string &str_path)
{unsigned long long pos = str_path.find_last_of("/");std::string filename=str_path.substr(pos + 1);return filename;
}int winhttpDownload(std::string Url, std::string FileName)
{std::wstring wUrl = StringToWString(Url);LPCWSTR pwszUrlwstr = wUrl.c_str();URL_COMPONENTS urlComp = { 0 };DWORD dwUrlLen = 0;// 初始化 URL_COMPONENTS 结构体.ZeroMemory(&urlComp, sizeof(urlComp));urlComp.dwStructSize = sizeof(urlComp);//分配空间存储,否则解析获取的信息格式不正确wchar_t* pScheme = new wchar_t[MAX_PATH]();wchar_t* pHostName = new wchar_t[MAX_PATH]();wchar_t* pUserName = new wchar_t[MAX_PATH]();wchar_t* pPassword = new wchar_t[MAX_PATH]();wchar_t* pUrlPath = new wchar_t[MAX_PATH]();wchar_t* pExtraInfo = new wchar_t[MAX_PATH]();urlComp.lpszScheme = pScheme;urlComp.lpszHostName = pHostName;urlComp.lpszUserName = pUserName;urlComp.lpszPassword = pPassword;urlComp.lpszUrlPath = pUrlPath;urlComp.lpszExtraInfo = pExtraInfo;// 设置必要的组件长度为非零,这样它们就可以被解析.(结构体连等赋值)urlComp.dwSchemeLength =urlComp.dwHostNameLength =urlComp.dwUserNameLength =urlComp.dwPasswordLength =urlComp.dwUrlPathLength =urlComp.dwExtraInfoLength = (DWORD)-1;//解析//if (!WinHttpCrackUrl(pwszUrlwstr, (DWORD)wcslen(pwszUrlwstr), 0, &urlComp))if (!WinHttpCrackUrl(pwszUrlwstr, 0, 0, &urlComp)){printf("Error %u in WinHttpCrackUrl.\n", GetLastError());}else{std::wstring wUrlPath = pUrlPath;std::string u8strUrl = uWStringTou8String(wUrlPath);std::string strUrlen = urlencode(u8strUrl); //UrlEncode后均为英文字符,ANSI与UTF-8无差别std::wstring wstrUrlen = StringToWString(strUrlen);//同样可以使用u8StringTouWString() 转换为UnicodeurlComp.lpszUrlPath = (LPWSTR)wstrUrlen.c_str();std::string strUrlde = urldecode(strUrlen);std::wstring u8UrlPath = u8StringTouWString(strUrlde);std::string strUrlPath = WStringToString(u8UrlPath);if (FileName.empty() == 1){FileName = GetFileName(strUrlPath);}LPCSTR lpFileNamestr = FileName.c_str();DWORD dwSize = 0;DWORD dwSumSize = 0;DWORD dwDownloaded = 0;DWORD dwBuffer = 0,dwBufferLength = sizeof(DWORD),dwIndex = 0;LPSTR pszOutBuffer;BOOL  bResults = FALSE;HINTERNET  hSession = NULL,hConnect = NULL,hRequest = NULL;HANDLE hFile;hFile = CreateFileA(lpFileNamestr,  // creates a new fileFILE_APPEND_DATA,         // open for writingFILE_SHARE_READ,          // allow multiple readersNULL,                     // no securityCREATE_ALWAYS,            // creates a new file, always.FILE_ATTRIBUTE_NORMAL,    // normal fileNULL);                    // no attr. templateif (hFile == INVALID_HANDLE_VALUE){printf("Could not creates %s.\n", lpFileNamestr);return 2;}// Use WinHttpOpen to obtain a session handle.hSession = WinHttpOpen(L"WinHTTP_Download Example/1.0",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS, 0);// Specify an HTTP server.//INTERNET_PORT nPort = (pGetRequest->fUseSSL) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;if (hSession)hConnect = WinHttpConnect(hSession, urlComp.lpszHostName,//hConnect = WinHttpConnect(hSession, L"avatar.csdn.net",INTERNET_DEFAULT_HTTPS_PORT, 0);// Create an HTTP request handle.if (hConnect)hRequest = WinHttpOpenRequest(hConnect, L"GET", urlComp.lpszUrlPath,L"HTTP/1.1", WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES,WINHTTP_FLAG_SECURE);// Send a request.if (hRequest)bResults = WinHttpSendRequest(hRequest,WINHTTP_NO_ADDITIONAL_HEADERS,0, WINHTTP_NO_REQUEST_DATA, 0,0, 0);// End the request.if (bResults)bResults = WinHttpReceiveResponse(hRequest, NULL);WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwBuffer, &dwBufferLength, &dwIndex);// Continue to verify data until there is nothing left.if (bResults)do{// Verify available data.dwSize = 0;if (!WinHttpQueryDataAvailable(hRequest, &dwSize))printf("Error %u in WinHttpQueryDataAvailable.\n",GetLastError());// Allocate space for the buffer.pszOutBuffer = new char[dwSize + (size_t)1];if (!pszOutBuffer){printf("Out of memory\n");dwSize = 0;}else{dwSumSize += dwSize;printf("Download: %0.2f%%\t%d\t%d\r", dwSumSize * 100.0 / dwBuffer, dwSumSize, dwBuffer); //计算已下载的百分比// Read the Data.ZeroMemory(pszOutBuffer, dwSize + (size_t)1);if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,dwSize, &dwDownloaded)) {printf("Error %u in WinHttpReadData.\n", GetLastError());}else {WriteFile(hFile, pszOutBuffer, dwDownloaded, &dwDownloaded, NULL);}// Free the memory allocated to the buffer.delete[] pszOutBuffer;}} while (dwSize > 0);// Close files.CloseHandle(hFile);// Report any errors.if (!bResults)printf("Error %d has occurred.\n", GetLastError());// Close open handles.if (hRequest) WinHttpCloseHandle(hRequest);if (hConnect) WinHttpCloseHandle(hConnect);if (hSession) WinHttpCloseHandle(hSession);delete[]pScheme;delete[]pHostName;delete[]pUserName;delete[]pPassword;delete[]pUrlPath;delete[]pExtraInfo;}return 0;
}int main(int argc, CHAR* argv[])
//"https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect"
{if (argc < 2){printf("Err: Must have at least one parameter. argc:%d(argc>=2)",argc);}else if (argc == 2){winhttpDownload(argv[1], "");}else{winhttpDownload(argv[1], argv[2]);}return 0;
}

逗是简单粗暴的用C++写的使用WinHTTP实现文件下载,不再被PowerShell安全策略支配(执行*.ps1脚本却忘记修改PowerShell的安全策略允许运行脚本),下载功能和 Invoke-WebRequest -Uri *** -OutFile *** 一样一样的。

WinHTTP实现文件下载 C++程序相关推荐

  1. C++ winhttp 实现文件下载器

    本篇内容讲述 C++ winHttp 实现下载器的简单 demo,使用了 WinHttpOpen.WinHttpConnect.WinHttpOpenRequest.WinHttpSendReques ...

  2. 微信小程序文件下载预览 真机调试可以 但直接预览打不开 小程序文件下载 小程序文件预览

    只要确保真机调试和调试状态下可以下载并预览文件即可,上线后即可预览成功 文件预览代码: 小程序预览的前提需要先调用下载接口,下方代码未处理下载和预览失败事件哟,此处我使用的是uniapp框架,如果使用 ...

  3. python写一个文件下载器_python使用tcp实现一个简单的下载器

    上一篇中介绍了tcp的流程,本篇通过写一个简单的文件下载器程序来巩固之前学的知识. 文件下载器的流程如下: 客户端: 输入目标服务器的ip和port 输入要下载文件的名称 从服务器下载文件保存到本地 ...

  4. php 弹出下载,php文件下载,不弹出下载框怎么破

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 求助~今天写了个文件下载的程序,从浏览器控制台看到接收到了服务器返回的数据,但是不弹出来下载框怎么破? 代码如下: public function dow ...

  5. 完成端口与高性能服务器程序开发

    早在两年前我就已经能很熟练的运用完成端口这种技术了,只是一直没有机会将它用在什么项目中,这段时间见到这种技术被过分炒作,过分的神秘化,就想写一篇解释它如何工作的文章.想告诉大家它没有传说中的那么高深难 ...

  6. 黑马程序员《JavaWeb程序设计案例教程》_课后习题答案

    第一章 [测一测] 学习完前面的内容,下面来动手测一测吧,请思考以下问题: 1.请描述HTML.CSS.DOM.JavaScript分别表示的含义. 2.请列举出HTML常用的标记.(至少10个) 3 ...

  7. 【传智播客】Javaweb程序设计任务教程 黑马程序员 第7,8,9,10,11,12,13,14,15章 课后答案

    所有章节答案合集-->传送门 第一部分是题目,向下翻, 第二部分是答案 第七章 [测一测] 学习完前面的内容,下面来动手测一测吧,请思考以下问题: 1.简述Javabean规范都有哪些?(至少写 ...

  8. 推荐几款网盘源码程序

    喜欢收集资源,喜欢分享资源,网盘无疑是必不可少的工具.百度.阿里网盘虽然很好用,但自己有硬盘和主机资源的,都想自建网盘存储数据,实现存储自由和数据安心. 本人经过测试,推荐以下几款开源网盘程序,希望大 ...

  9. 个人小程序智能对话查询工具完整代码分享--快递、身份证、词典、诗词等

    这篇文章的原文地址:http://blog.csdn.net/huangmeimao/article/details/76418753 转载请标明出处,谢谢. 我们经常在电影中看到机器和人对答如流,随 ...

  10. java下载文件下载不动_java文件下载的问题

    以前没写过文件下载的程序,现在在servlet中试了试,有些问题请教大神.代码如下:publicvoiddoPost(HttpServletRequestrequest,HttpServletResp ...

最新文章

  1. 生成随机验证图片--ASP.NET中常用代码之二
  2. leetcode算法题--连续差相同的数字
  3. 2 datax mysql 和 mysql之间相互导入
  4. Windows进程与线程学习笔记(九)—— 线程优先级/进程挂靠/跨进程读写
  5. 常见的数据库管理系统排名(DBMS)
  6. poj 2976 基础01分数规划
  7. 低碳数据中心,因何而来?一文读懂如何利用超融合降碳
  8. c语言吸收最后一个空格,新人提问:如何将输出时每行最后一个空格删除
  9. 修改linux软件下载,Linux软件下载以及修改环境变量
  10. 区块链 以太坊 solidity require revert assert
  11. [wcf]入门.3.1
  12. concurrenthashmap获取不到_面试必问的ConcurrentHashMap
  13. 单片机仿真软件Proteus8.0的安装及使用
  14. Swift版百思不得姐
  15. Compiz Fusion 简介
  16. Android Mms短信的发送流程,短信发送源码解析
  17. 成为顶尖的AI算法工程师,你该具备些什么?
  18. Ubuntu 输入法设置
  19. “无剑胜有剑”软件大师之路的一点探索
  20. hadoop 错误锦集

热门文章

  1. 最佳网络工具--OpManager局域网管理软件
  2. Python 2.7 (64位) 出现bug,idle不能打开
  3. 破解版软件-20131014更新
  4. 关于使用tess4j-OCR识别图片中文教程,亲测可用,不报错
  5. 计算机设计大赛物联网专项赛专栏
  6. 关于Faster Rcnn的一些理解
  7. 八个方向调节的云台控制器
  8. 一行.bat代码实现win+L锁定计算机立即锁屏
  9. cpu压测 windows_小白求问怎么用AIDA64进行CPU压力测试
  10. 高斯模糊 高斯核函数