C++/WinAPI 中的 .NET WebClient.DownloadData(url) 替代方案?

Posted

技术标签:

【中文标题】C++/WinAPI 中的 .NET WebClient.DownloadData(url) 替代方案?【英文标题】:.NET WebClient.DownloadData(url) alternative in C++/WinAPI? 【发布时间】:2011-03-30 09:20:32 【问题描述】:

如何使用 C++ 在线获取文件的内容?

【问题讨论】:

【参考方案1】:

您可以通过多种方式做到这一点。

WinInet

首先,Windows 有一个内置的 API,允许您发出 HTTP 请求,使用起来相当简单。我使用这个简单的包装类来下载文件:

/**
 * Simple wrapper around the WinInet library.
 */
class Inet

public:
    explicit Inet() : m_hInet(NULL), m_hConnection(NULL)
    
        m_hInet = ::InternetOpen(
            "My User Agent",
            INTERNET_OPEN_TYPE_PRECONFIG,
            NULL,
            NULL,
            /*INTERNET_FLAG_ASYNC*/0);
    

    ~Inet()
    
        Close();

        if (m_hInet)
        
            ::InternetCloseHandle(m_hInet);
            m_hInet = NULL;
        
    

    /**
     * Attempt to open a URL for reading.
     * @return false if we don't have a valid internet connection, the url is null, or we fail to open the url, true otherwise.
     */
    bool Open(LPCTSTR url)
    
        if (m_hInet == NULL)
        
            return false;
        

        if (url == NULL)
        
            return false;
        

        m_hConnection = ::InternetOpenUrl(
            m_hInet,
            url,
            NULL /*headers*/,
            0 /*headers length*/,
            INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI, 
            reinterpret_cast<DWORD_PTR>(this));

        return m_hConnection != NULL;
    

    /**
     * Read from a connection opened with Open.
     * @return true if we read data.
     */
    bool ReadFile(LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD dwRead)
    
        ASSERT(m_hConnection != NULL);

        return ::InternetReadFile(m_hConnection, lpBuffer, dwNumberOfBytesToRead, dwRead) != 0;
    

    /**
     * Close any open connection.
     */
    void Close()
    
        if (m_hConnection != NULL)
        
            ::InternetCloseHandle(m_hConnection);
            m_hConnection = NULL;
        
    

private:
    HINTERNET m_hInet;
    HINTERNET m_hConnection;
;

这个用法很简单:

Inet inet;
if (inet.Open(url))

    BYTE buffer[UPDATE_BUFFER_SIZE];
    DWORD dwRead;
    while (inet.ReadFile(&buffer[0], UPDATE_BUFFER_SIZE, &dwRead))
    
        // TODO: Do Something With buffer here
        if (dwRead == 0)
        
            break;
        
    

LibCurl

如果您宁愿避免使用特定于 Windows 的 API,那么您可能会比使用 libcurl 库使用各种协议(包括 HTTP)获取文件更糟糕。有一个很好的示例展示了如何将 URL 直接检索到内存中(避免下载到磁盘):getinmemory sample。

【讨论】:

感谢您的精彩回答!【参考方案2】:

使用以下函数。

WinHttpConnect
WinHttpOpenRequest
WinHttpSendRequest
WinHttpReceiveResponse
WinHttpQueryDataAvailable
WinHttpReadData

【讨论】:

以上是关于C++/WinAPI 中的 .NET WebClient.DownloadData(url) 替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

C# WinAPI 从静态检查窗口文本

通过WinAPI播放PCM声音

.NET(C#) SendKeys模拟键盘按键不生效使用WinAPI的替代方案

.net 调用 winapi获取窗口句柄和内容

C winapi 进程间通信(Named Pipe)。

C#。 WinApi。在窗口上绘制