InternetReadFileEx的参数不正确错误

时间:2016-10-01 20:01:10

标签: c++ file

所以我试图从我使用WinInet函数的网站中的文件中读取,所以我能够成功地完成所有的InternetConnect()函数和东西,但是当我尝试做InternetReadFileExA()时,我不断收到错误87这意味着参数不正确,当然它并没有告诉我哪一个我不正确所以我不知道如何解决它,我认为它可能是我设置为NULL的函数中的第四个参数因为像往常一样微软从不告诉你如何获取特定的值,它所说的是“调用者提供的用于异步操作的上下文值”。它并没有告诉我应该使用什么价值。任何人都可以告诉我我有什么问题以及如何解决它?这是我的代码

HANDLE fileToSend;
HINTERNET iNetOpenHandle = InternetOpen(L"FileTransfer", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);

using namespace std;

int main()
{
    HINTERNET connectHandle = InternetConnect(iNetOpenHandle, L"IMhidingTheIpHere", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_NO_CALLBACK, NULL);

    PCWSTR acceptTypes[2] = {L"text/html", NULL};
    HINTERNET httpReq = HttpOpenRequest(connectHandle, NULL, L"Tutorials.html", NULL, L"http://www.dominihq.hoxty.com/Tutorials.html", acceptTypes, INTERNET_FLAG_RELOAD, NULL);



    if (httpReq != NULL) {
        cout << "Opened http request successfully" << endl;
    }
    else {
        cout << "Could not open http request" << endl;
        int errCode = GetLastError();
        cout << "Error Code: " << errCode << endl;
    }

    INTERNET_BUFFERSA iNetBuffer;
    bool readFileStatus = InternetReadFileExA(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

    if (readFileStatus == true) {
        cout << "ReadFile completed successfully!" << endl;
        cout << "Data: " << iNetBuffer.lpvBuffer << endl;
    }
    else {
        cout << "Could not read file" << endl;
        int errCode = GetLastError();
        cout << "Error Code: " << errCode << endl;
    }

    system("Pause");
    return 0;
}

以下是错误

的部分
bool readFileStatus = InternetReadFileExA(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

2 个答案:

答案 0 :(得分:0)

HttpOpenRequest需要InternetConnect创建的句柄。它会创建另一个句柄,然后由HttpSendRequest使用。

您只是在阅读网页,因此您不需要任何此类网页。使用InternetOpenUrl代替HttpOpenRequest。您可以使用InternetReadFile代替InternetReadFileEx。确保关闭手柄。

#define UNICODE
#include <iostream>
#include <string>
#include <fstream>
#include <Windows.h>
#include <WinInet.h>

#pragma comment(lib, "wininet.lib")//Visual Studio specific pragma for adding library

int main()
{
    std::string str;

    HINTERNET iNetOpenHandle = InternetOpen(L"FileTransfer", 
        INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (iNetOpenHandle)
    {
        HINTERNET hurl = InternetOpenUrl(iNetOpenHandle, 
            L"http://www.dominihq.hoxty.com/Tutorials.html", NULL, 0,
            INTERNET_FLAG_DONT_CACHE, 0);
        if (hurl)
        {
            DWORD received;
            const int bufsize = 1024;
            char buf[bufsize];
            while (InternetReadFile(hurl, buf, bufsize, &received))
            {
                if (!received) break;

                //show progress...
                std::cout << ".";
                str.append(buf, received);
            }
            std::cout << "\n";
            InternetCloseHandle(hurl);
        }
        InternetCloseHandle(iNetOpenHandle);
    }

    std::ofstream f(L"filename.htm");
    f << str;

    return 0;
}

请注意,结果可能是UTF-8,如果要直接在Windows中显示结果,可能需要使用MultiByteToWideChar将UTF-8转换为UTF-16。

答案 1 :(得分:0)

如果我们接受您的代码,请修复丢失的包含,然后粘贴到online Visual Studio compiler

#include <Windows.h>
#include <Wininet.h>
#include <WinSock.h>
#include <iostream>

HANDLE fileToSend;
HINTERNET iNetOpenHandle = InternetOpen(L"FileTransfer", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);

using namespace std;

int main()
{
    HINTERNET connectHandle = InternetConnect(iNetOpenHandle, L"IMhidingTheIpHere", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_NO_CALLBACK, NULL);

    PCWSTR acceptTypes[2] = {L"text/html", NULL};
    HINTERNET httpReq = HttpOpenRequest(connectHandle, NULL, L"Tutorials.html", NULL, L"http://www.dominihq.hoxty.com/Tutorials.html", acceptTypes, INTERNET_FLAG_RELOAD, NULL);



    if (httpReq != NULL) {
        cout << "Opened http request successfully" << endl;
    }
    else {
        cout << "Could not open http request" << endl;
        int errCode = GetLastError();
        cout << "Error Code: " << errCode << endl;
    }

    INTERNET_BUFFERSA iNetBuffer;
    bool readFileStatus = InternetReadFileExA(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

    if (readFileStatus == true) {
        cout << "ReadFile completed successfully!" << endl;
        cout << "Data: " << iNetBuffer.lpvBuffer << endl;
    }
    else {
        cout << "Could not read file" << endl;
        int errCode = GetLastError();
        cout << "Error Code: " << errCode << endl;
    }

    system("Pause");
    return 0;
}

我们可以看到默认项目设置为我们提供了许多与字符类型转换相关的警告 - 您指定的是L".."而不是_T("..."),只有在我们使用Unicode / MBCS时才可以。

source_file.cpp(7): error C2664: 'HINTERNET InternetOpenA(LPCSTR,DWORD,LPCSTR,LPCSTR,DWORD)': cannot convert argument 1 from 'const wchar_t [13]' to 'LPCSTR'
source_file.cpp(7): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
source_file.cpp(13): error C2664: 'HINTERNET InternetConnectA(HINTERNET,LPCSTR,INTERNET_PORT,LPCSTR,LPCSTR,DWORD,DWORD,DWORD_PTR)': cannot convert argument 2 from 'const wchar_t [18]' to 'LPCSTR'
source_file.cpp(13): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
source_file.cpp(16): error C2664: 'HINTERNET HttpOpenRequestA(HINTERNET,LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPCSTR *,DWORD,DWORD_PTR)': cannot convert argument 3 from 'const wchar_t [15]' to 'LPCSTR'
source_file.cpp(16): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

这告诉我们的是你有一个字符宽度问题,而且确实

INTERNET_BUFFERSA iNetBuffer;
bool readFileStatus = InternetReadFileExA(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

您正在指定字符类型结构和功能。

如果我们启用Unicode和remove your 'A' specifiers

    INTERNET_BUFFERS iNetBuffer;
    bool readFileStatus = InternetReadFileEx(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

然后程序编译(它没有链接到rextester,因为我没有指定要包含的库)。

在任何时候我都无法使用VS2015,VS2013或VS2010重现您报告的模糊错误,但随后我扩展了描述框,以便我可以阅读所有内容。

  • 除非您尝试编写可移植代码,否则请避免使用L"",在这种情况下,您无论如何都不会使用Windows特定的调用。请改用_T("...")

    InternetOpen(_T(&#34; FileTransfer&#34;),INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,INTERNET_FLAG_ASYNC);

  • 除非您明确要求,否则请避免使用A / W后缀(例如,您只能编写函数以获取&#39; char *&#39;指针)

    INTERNET_BUFFERS iNetBuffer;
    bool readFileStatus = InternetReadFileEx(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);
    

请注意,Microsoft的BOOL类型与bool不同,因此您可能需要考虑将最后一行写为

    BOOL readFileStatus = InternetReadFileEx(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);

    auto readFileStatus = InternetReadFileEx(httpReq, &iNetBuffer, WININET_API_FLAG_ASYNC, NULL);