首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

URLDownloadToFile API 實現簡易檔案下載 (C++/Win32)

     編輯:VC 教學

簡介

URLDownloadToFile (位於 Urlmon.dll, 引入 Urlmon.lib) 是 Windows 提供的高層下載 API,支援 HTTP/HTTPS/FTP、自動處理 Proxy、重導向、斷點續傳 (需自行實作 Range)、進度回呼。適合簡單下載需求,無需手寫 WinInet/Socket 代碼。

最小完整範例 (主控台)

#include 
#include 
#include 
#pragma comment(lib, "urlmon.lib")

// 進度回呼介面實作 (可選)
class DownloadCallback : public IBindStatusCallback {
    LONG m_ref = 1;
public:
    STDMETHODIMP QueryInterface(REFIID riid, void** ppv) {
        if (riid == IID_IUnknown || riid == IID_IBindStatusCallback) {
            *ppv = this; AddRef(); return S_OK;
        }
        *ppv = nullptr; return E_NOINTERFACE;
    }
    STDMETHODIMP_(ULONG) AddRef() { return InterlockedIncrement(&m_ref); }
    STDMETHODIMP_(ULONG) Release() {
        ULONG r = InterlockedDecrement(&m_ref);
        if (r == 0) delete this;
        return r;
    }
    STDMETHODIMP OnProgress(ULONG ulProgress, ULONG ulProgressMax,
                            ULONG ulStatusCode, LPCWSTR szStatusText) {
        if (ulProgressMax) {
            int pct = ulProgress * 100 / ulProgressMax;
            std::wcout << L"\r進度: " << pct << L"% (" << ulProgress << L"/" << ulProgressMax << L")";
        }
        return S_OK;
    }
    // 其他純虛函數回傳 S_OK 或 E_NOTIMPL
    STDMETHODIMP OnStartBinding(DWORD, IBinding*) { return S_OK; }
    STDMETHODIMP GetPriority(LONG*) { return S_OK; }
    STDMETHODIMP OnDataAvailable(DWORD, DWORD, FORMATETC*, STGMEDIUM*) { return S_OK; }
    STDMETHODIMP OnObjectAvailable(REFIID, IUnknown*) { return S_OK; }
    STDMETHODIMP OnLowResource(DWORD) { return S_OK; }
    STDMETHODIMP OnStopBinding(HRESULT, LPCWSTR) { return S_OK; }
    STDMETHODIMP GetBindInfo(DWORD*, BINDINFO*) { return E_NOTIMPL; }
};

int wmain() {
    DownloadCallback cb;
    HRESULT hr = URLDownloadToFile(
        nullptr,                           // pCaller
        L"https://example.com/file.zip",    // szURL
        L"D:\\downloads\\file.zip",        // szFileName
        0,                                 // dwReserved
        &cb                                // lpfnCB
    );
    if (SUCCEEDED(hr))
        std::wcout << L"\n下載成功!\n";
    else
        std::wcerr << L"\n失敗: 0x" << std::hex << hr << std::endl;
    return 0;
}

關鍵參數說明

  • pCaller:通常傳 nullptr;若在 ActiveX/IE 宿主中可傳容器 IUnknown。
  • szURL:支援 https://, https://, ftp://, file://。
  • szFileName:本地完整路徑,**目錄必須存在**,函數不建立目錄。
  • dwReserved:保留,必須為 0。
  • lpfnCB:IBindStatusCallback 指標,提供進度、暫停/繼續、驗證等控制。傳 nullptr 為靜默下載。

常見回傳碼

HRESULT含義
S_OK (0)成功
E_OUTOFMEMORY記憶體不足
INET_E_DOWNLOAD_FAILURE網路/伺服器錯誤
INET_E_RESOURCE_NOT_FOUND404 Not Found
E_ACCESSDENIED權限不足 (寫入目標/網路存取)
S_FALSE使用者取消 (回呼傳回 E_ABORT)

進階功能

  • 斷點續傳:回呼中 OnProgress 記錄已下載位元組,重啟時需自行發送 Range 標頭 (需用 IBindStatusCallback::GetBindInfo 設定 BINDINFO 的 szExtraInfo),或改用 WinInet 手動控制。
  • 非同步下載:在獨立執行緒呼叫 URLDownloadToFile,主執行緒保持響應。
  • Proxy 設定:自動讀取 IE/系統 Proxy 設定,可用 InternetSetOption 覆寫。

適用場景與限制

  • ✅ 簡單工具、安裝程式下載更新、小檔案自動更新。
  • ❌ 大檔案需精細進度控制、多執行緒分段、限速、斷點續傳健壯性 → 改用 WinInet / WinHTTP / libcurl。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved