2013-12-22 97 views
0

我正在創建一個程序,可以從互聯網上下載文件。 之前,我下載的文件,我想獲得的文件大小,我都試過InternetQueryDataAvailable,但它給出了0從互聯網下載文件,HttpSendRequest失敗,錯誤代碼

然後我試圖hHttpRequest的值,但它給錯誤代碼ERROR_HTTP_HEADER_NOT_FOUND。所以我添加了HttpSendRequest,但它給出錯誤代碼ERROR_INTERNET_INVALID_URL。

我使用的是平均站點作爲測試場地: 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; 
} 

回答

3

當調用InternetConnect(),僅指定"download.avgfree.com"本身的主機名,而不是URL。

當致電HttpOpenRequest()時,請指定"/filedir/inst/avg_free_x86_all_2014_4259a6848.exe"作爲要請求的對象,而不是文件名本身。

使用InternetCrackUrl()劃分一個完整的URL到其各個組成部分,經過lpszHostNamenPort領域InternetConnect()lpszUrlPath領域HttpOpenRequest()

您也不需要知道文件大小以便下載。事實上,在下載開始時,有些時候沒有文件大小。有時候會有。無論哪種方式,您都可以直接調用InternetReadFile(),直到它報告沒有更多數據可以接收爲止。讓它在內部爲您處理文件大小。

順便說一句,看看URLDownloadToFile()函數。讓它爲你處理這些細節。

+0

感謝您的快速和偉大的答案。對於任何使用HttpQueryInfo獲取文件大小的用戶,請確保包含HTTP_QUERY_FLAG_NUMBER標誌。 – AlwaysNub