因为要项目中要想要实现一个软件自动更新的功能,之前是使用socket直接下载。但切换下载源的时候很麻烦。所以换用http方式。

网上找了很多资料,基本上就是下面几种:

1.curllib //功能强大太但太麻烦而且没必要

2.MFC自带的功能 // 项目不是使用的MFC所以舍

3.IE控件下载 // 没办法获取到进度,而且因为不能获取到总大小所以很容易下载的资源不完整。

思来想去,最后还是使用WinHTTP,比较简单快捷,而且功能上基本上都能够满足。

#include <stdio.h>
#include <Windows.h>
#include <Winhttp.h>
#pragma comment(lib,"Winhttp.lib") typedef void(*DownLoadCallback)(int ContentSize, int CUR_LEN); typedef struct _URL_INFO
{
WCHAR szScheme[512];
WCHAR szHostName[512];
WCHAR szUserName[512];
WCHAR szPassword[512];
WCHAR szUrlPath[512];
WCHAR szExtraInfo[512];
}URL_INFO, *PURL_INFO; void dcallback(int ContentSize, int file_size)
{
printf("count:%d,size:%d\n", ContentSize, file_size);
} void download(const wchar_t *Url, const wchar_t *FileName, DownLoadCallback Func)
{
URL_INFO url_info = { 0 };
URL_COMPONENTSW lpUrlComponents = { 0 };
lpUrlComponents.dwStructSize = sizeof(lpUrlComponents);
lpUrlComponents.lpszExtraInfo = url_info.szExtraInfo;
lpUrlComponents.lpszHostName = url_info.szHostName;
lpUrlComponents.lpszPassword = url_info.szPassword;
lpUrlComponents.lpszScheme = url_info.szScheme;
lpUrlComponents.lpszUrlPath = url_info.szUrlPath;
lpUrlComponents.lpszUserName = url_info.szUserName; lpUrlComponents.dwExtraInfoLength =
lpUrlComponents.dwHostNameLength =
lpUrlComponents.dwPasswordLength =
lpUrlComponents.dwSchemeLength =
lpUrlComponents.dwUrlPathLength =
lpUrlComponents.dwUserNameLength = 512; WinHttpCrackUrl(Url, 0, ICU_ESCAPE, &lpUrlComponents); // 创建一个会话
HINTERNET hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
DWORD dwReadBytes, dwSizeDW = sizeof(dwSizeDW), dwContentSize, dwIndex = 0;
// 创建一个连接
HINTERNET hConnect = WinHttpConnect(hSession, lpUrlComponents.lpszHostName, lpUrlComponents.nPort, 0);
// 创建一个请求,先查询内容的大小
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"HEAD", lpUrlComponents.lpszUrlPath, L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH);
WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
WinHttpReceiveResponse(hRequest, 0);
WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwContentSize, &dwSizeDW, &dwIndex);
WinHttpCloseHandle(hRequest); // 创建一个请求,获取数据
hRequest = WinHttpOpenRequest(hConnect, L"GET", lpUrlComponents.lpszUrlPath, L"HTTP/1.1", WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH);
WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
WinHttpReceiveResponse(hRequest, 0); // 分段回调显示进度
DWORD BUF_LEN = 1024, ReadedLen = 0;
BYTE *pBuffer = NULL;
pBuffer = new BYTE[BUF_LEN]; HANDLE hFile = CreateFileW(FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); while (dwContentSize > ReadedLen)
{
ZeroMemory(pBuffer, BUF_LEN);
WinHttpReadData(hRequest, pBuffer, BUF_LEN, &dwReadBytes);
ReadedLen += dwReadBytes; // 写入文件
WriteFile(hFile, pBuffer, dwReadBytes, &dwReadBytes, NULL);
// 进度回调
Func(dwContentSize, ReadedLen); } CloseHandle(hFile);
delete pBuffer; /*
// 一次性写入整个文件
BYTE *pBuffer = NULL; pBuffer = new BYTE[dwContentSize];
ZeroMemory(pBuffer, dwContentSize);
//do{
WinHttpReadData(hRequest, pBuffer, dwContentSize, &dwReadBytes);
Func(dwContentSize, dwReadBytes);
//} while (dwReadBytes == 0); HANDLE hFile = CreateFileW(FileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, pBuffer, dwContentSize, &dwReadBytes, NULL);
CloseHandle(hFile); delete pBuffer;
*/
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession); } int main(int argc, char* argv[])
{
download(L"http://sw.bos.baidu.com/sw-search-sp/software/58d7820029ae7/BaiduMusic_10.1.7.7_setup.exe", L"./BaiduMusic_10.1.7.7_setup.exe", &dcallback);
system("pause");
}

c++ 使用WinHTTP实现文件下载功能的更多相关文章

  1. JAVA文件下载功能问题解决日志

    今天给报告系统做了个下载功能,遇到了挺多问题,通过查资料一一解决了. 1.首先遇到的问题是:java后台的输出流输出之后,没有任何报错,浏览器端不弹出保存文件的对话框,原本是ajax请求到后台的con ...

  2. 解决springmvc中文件下载功能中使用javax.servlet.ServletOutputStream out = response.getOutputStream();后运行出异常但结果正确的问题

    问题描述: 在springmvc中实现文件下载功能一般都会使用javax.servlet.ServletOutputStream out = response.getOutputStream();封装 ...

  3. WebView实现文件下载功能

    WebView控制调用相应的WEB页面进行展示.安卓源码当碰到页面有下载链接的时候,点击上去是一点反应都没有的.原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置W ...

  4. Spring Boot实现文件下载功能

    我们只需要创建一个控制器(Controler)文件,即Controller目录下的File_Download.java,其完整目录如下: @Controller public class File_D ...

  5. Spring Boot入门(11)实现文件下载功能

      在这篇博客中,我们将展示如何在Spring Boot中实现文件的下载功能.   还是遵循笔者写博客的一贯风格,简单又不失详细,实用又能让你学会.   本次建立的Spring Boot项目的主要功能 ...

  6. ASP.NET网页中RAR、DOC、PDF等文件下载功能实例源代码

    以前做asp.net下载功能的时候都是采用:<a href="http://www.wang0214.com/wgcms">下载</a>的方式来实现下载. ...

  7. java web文件下载功能实现 (转)

    http://blog.csdn.net/longshengguoji/article/details/39433307 需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一 ...

  8. 【Servlet】java web 文件下载功能实现

    需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 <!DOCTYPE html> & ...

  9. ASP.NET MVC 向浏览器发送文件以提供文件下载功能

    撑到大三了,结果发现周围的同学更加堕落了,尤其是某些人,表面上看起来很认真,实际上三天打鱼,两天晒网,结果一事无成,却还要抱怨学校教育失败. 为了吸取他们的教训,就算是一个小小的编码问题,我也要努力解 ...

随机推荐

  1. Java技术大牛需要学习的25个技能

    你需要精通面向对象分析与设计(OOA/OOD).涉及模式(GOF,J2EEDP)以及综合模式.你应该了解UML,尤其是class.object.interaction以及statediagrams. ...

  2. 通过virt-manager 利用NFS创建、迁移虚拟机2

    前面一篇文章介绍了利用NFS创建虚拟机的过程,本文就介绍下如何利用NFS对虚拟机进行动态迁移. 动态迁移就是把一台虚拟机在不停止其运行的情况下迁移到另一台物理机上.这看起来似乎不太可能,不过还好kvm ...

  3. 网络爬虫之scrapy框架设置代理

    前戏 os.environ()简介 os.environ()可以获取到当前进程的环境变量,注意,是当前进程. 如果我们在一个程序中设置了环境变量,另一个程序是无法获取设置的那个变量的. 环境变量是以一 ...

  4. str文档

    文档 class str(object): """ str(object='') -> str str(bytes_or_buffer[, encoding[, e ...

  5. python web 程序的9种部署方式

    python有很多web 开发框架,代码写完了,部署上线是个大事,通常来说,web应用一般是三层结构 Web Server====>    Application=====>   DB S ...

  6. Data striping

    条带化是把连续的数据分割成相同大小的数据块,把每段数据分别写入到阵列中的不同磁盘上的方法. 当多个进程同时访问一个磁盘时,可能会出现磁盘冲突.大多数磁盘系统都对访问次数(每秒的 I/O 操作,IOPS ...

  7. mytest3.py-api接入平台获取数据

    mytest3.py-api接入平台获取数据 import base64 import datetime import hashlib import urllib import urllib.pars ...

  8. python web框架 Django 登录页面

    在django 项目下 创建一个templates 放模板的文件夹 html文件都放在这里 在里面写一个login.html 登录页面 urls.py 加上 login 对应关系 from djang ...

  9. webuploader 多图片上传

    WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件. 具体接口参考 webuploader接口文档地址 一.图片上传功能 ...

  10. Linux服务器access_log日志分析及配置详解(二)

    默认nginx / Linux日志在哪个文件夹? 一般在 xxx.xxx.xxxx.com/home/admin 路径下面的error.log文件和access.log文件error_log logs ...