首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >win32 GetConsoleMode()错误代码6

win32 GetConsoleMode()错误代码6
EN

Stack Overflow用户
提问于 2015-11-02 11:15:15
回答 1查看 4.4K关注 0票数 1

下面是另一篇文章中的示例,Reading a password from std::cin,在这里,您将句柄抓取到标准输入,获取当前控制台模式,将模式更改为抑制输入回显。由于某些原因,当我调用GetStdHandle()时,它返回一个有效句柄,但是当我调用GetConsoleMode()时,它会失败并返回错误代码6。是否应该设置任何调试标志以使其按预期工作?还有其他人遇到过这个吗?

代码语言:javascript
复制
void set_stdin_echo(bool enable) {
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    if (hStdin == INVALID_HANDLE_VALUE) {
        std::cout << "invalid handle " << GetLastError() << std::endl;
        return;
    }
    else if (hStdin == NULL) {
        std::cout << "no handle associated" << std::endl;
        return;
    }

    DWORD mode = 0;
    if (GetConsoleMode(hStdin, &mode) == 0) {
        std::cout << "Could not get console mode" << GetLastError() << std::endl;
    }

    std::cout << mode << std::endl;
    if (!enable)
        mode &= ~ENABLE_ECHO_INPUT;
    else
        mode |= ENABLE_ECHO_INPUT;
    std::cout << mode << std::endl;

    if (SetConsoleMode(hStdin, mode) == 0) {
        std::cout << "Could not set input mode" << std::endl;
        std::cout << GetLastError() << std::endl;
    }
}

编辑:用此代码复制。

CMakeLists.txt

代码语言:javascript
复制
cmake_minimum_required (VERSION 2.6)
project(tester)

if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-g -w -Wall -pedantic-errors -std=c++11")
elseif(MSVC)
    set(CMAKE_CXX_FLAGS "/EHsc")
    set(CMAKE_CXX_FLAGS_DEBUG "/EHsc /MTd")
    set(CMAKE_CXX_FLAGS_RELEASE "/EHsc /MT")
endif()

set(SOURCE_FILES "main.cpp")

add_executable(tester ${SOURCE_FILES})

main.cpp

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <windows.h>

void set_stdin_echo(bool enable) {
    DWORD error;
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    error = GetLastError();
    if (hStdin == INVALID_HANDLE_VALUE) {
        std::cout << "invalid handle " << error << std::endl;
        return;
    }
    else if (hStdin == NULL) {
        std::cout << "no handle associated" << std::endl;
        return;
    }

    DWORD mode = 0;
    if (GetConsoleMode(hStdin, &mode) == 0) {
        error = GetLastError();
        std::cout << "Could not get console mode" << error << std::endl;
    }

    std::cout << mode << std::endl;
    if (!enable)
        mode &= ~ENABLE_ECHO_INPUT;
    else
        mode |= ENABLE_ECHO_INPUT;
    std::cout << mode << std::endl;

    if (SetConsoleMode(hStdin, mode) == 0) {
        error = GetLastError();
        std::cout << "Could not set input mode" << std::endl;
        std::cout << error << std::endl;
    }
}

int main() {
    std::string input;
    std::cout << "password: ";
    set_stdin_echo(false);
    std::cin >> input;
    set_stdin_echo(true);

    return 0;
}

Visual 12.在某个目录中调用这些文件。我得到“无法获得控制台模式6",这意味着GetLastError()返回6。

代码语言:javascript
复制
mkdir build
cmake ..
msbuild.exe tester.sln
./Debug/tester.exe

编辑:这似乎只有在从命令行运行时才会失败。在visual studio调试器的visual studio中,它会成功。仍然没有足够的视觉工作室的知识来决定发生了什么。我只想制作一个简单的exe,它可以从命令行运行并隐藏它的输入。

编辑:清洁,并在调用后尽快获得GetLastError。还是没变。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-02 14:43:07

此错误6意味着“无效句柄”,并意味着您传递给GetConsoleMode的句柄不是控制台句柄。也就是说,STDIN已经被从某个地方重定向。

为了确保您拥有当前控制台的句柄,无论STDIN是否从其他地方重定向,请使用带有特殊名称的CreateFile (如果存在的话),它将打开控制台。

示例:

代码语言:javascript
复制
HANDLE hConsole = CreateFile("CONIN$",  
    GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 
    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33476316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档