【问题标题】:The parameter is incorrect error with InternetReadFileExInternetReadFileEx 参数不正确错误
【发布时间】:2016-10-01 20:01:09
【问题描述】:

所以我试图从我使用 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);

【问题讨论】:

  • “调用者提供的用于异步操作的上下文值。”表示如果您注册了异步回调,则它是您选择传递给您自己的函数的值。
  • 您实际上可能有错误的值。您应该在执行任何其他系统调用之前获得错误代码 first(当您使用 cout 输出时会发生这种情况)。
  • 你为什么叫“InternetReadFileExA”而不是“InternetReadFileEx”?

标签: c++ file


【解决方案1】:

如果我们获取您的代码,请修复缺少的包含,然后粘贴到 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("FileTransfer"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC);

  • 避免使用 A/W 后缀,除非绝对必须(例如,您只能编写函数来获取 'char*' 指针)

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

注意微软的BOOL类型和bool不一样,所以你可能要考虑把最后一行写成

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

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

【讨论】:

    【解决方案2】:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2019-08-03
      • 1970-01-01
      相关资源
      最近更新 更多