我正在创建一个可以从互联网上下载文件的程序。 在我下载文件之前,我想获取文件大小,我尝试过InternetQueryDataAvailable,但它的值为0.
然后我尝试了hHttpRequest,但它提供了错误代码ERROR_HTTP_HEADER_NOT_FOUND。所以我添加了HttpSendRequest,但它给出了错误代码ERROR_INTERNET_INVALID_URL。
我正在使用avg网站作为测试网站: http://free.avg.com/us-en/download-free-all-product
要下载的文件: avg_free_x86_all_2014_4259a6848.exe
任何帮助都会很好,谢谢。
代码:
DWORD DownloadFile(PCHAR SaveDirectory)
{
HINTERNET hInternet;
CHAR StrBuffer[100];
hInternet = InternetOpen(InternetAgent, PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0);
if (hInternet != NULL)
{
CHAR TestUrl[] = "http://download.avgfree.com/filedir/inst";
CHAR TestFileName[] = "avg_free_x86_all_2014_4259a6848.exe";
HINTERNET hHttpSession = InternetConnect(hInternet, TestUrl, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hHttpSession != NULL)
{
PCTSTR AcceptTypes[] = {"text/*", "application/exe", "application/zlib", "application/gzip", "application/applefile", NULL};
//I dont think application/exe is valid, but i could Not find a .exe format in the msdn list.
//http://www.iana.org/assignments/media-types/media-types.xhtml#application for the list
HINTERNET hHttpRequest = HttpOpenRequest(hHttpSession, "GET", TestFileName, "HTTP/1.1", TestUrl, &AcceptTypes[0],
INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE, 0);
if (hHttpRequest != NULL)
{
DWORD FileSize = 0;
DWORD BufferLength = sizeof(FileSize);
if (HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0))
{
//See if HttpQueryInfo can get the file size.
if (HttpQueryInfo(hHttpRequest, HTTP_QUERY_CONTENT_LENGTH, &FileSize, &BufferLength, NULL))
{
sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", FileSize);
MessageBox(MainWinHwnd, StrBuffer, "File Size", MB_OK);
}
else MessageBox(MainWinHwnd, "Failed to get the file size.", NULL, MB_OK);
//See if InternetQueryDataAvailable can get the file size.
if (InternetQueryDataAvailable(hHttpRequest, &FileSize, 0, 0))
{
sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", FileSize);
MessageBox(MainWinHwnd, StrBuffer, "File Size", MB_OK);
}
else
{
MessageBox(MainWinHwnd, "Failed to get the file size.", NULL, MB_OK);
}
}
else
{
DWORD LastError = GetLastError();
sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", LastError);
MessageBox(NULL, StrBuffer, NULL, MB_OK);
}
InternetCloseHandle(hHttpRequest);
}
else MessageBox(NULL, "Error #3", NULL, MB_OK);
InternetCloseHandle(hHttpSession);
}
else MessageBox(NULL, "Error #2", NULL, MB_OK);
InternetCloseHandle(hInternet);
}
else MessageBox(NULL, "Error #1", NULL, MB_OK);
return TRUE;
}
答案 0 :(得分:4)
调用InternetConnect()
时,仅为主机名指定"download.avgfree.com"
,而不是URL。
调用HttpOpenRequest()
时,请指定"/filedir/inst/avg_free_x86_all_2014_4259a6848.exe"
作为要请求的对象,而不是文件名。
使用InternetCrackUrl()
将完整网址划分为各个组件,将lpszHostName
和nPort
字段传递到InternetConnect()
,将lpszUrlPath
字段传递给{{ 1}}。
您也无需知道文件大小即可下载。事实上,有时下载开始时不知道文件大小。有时会有。无论哪种方式,您只需在循环中调用HttpOpenRequest()
,直到它报告无法接收更多数据。让它在内部为您处理文件大小。
BTW,看一下URLDownloadToFile()
函数。让它为您处理这些细节。