简体   繁体   English

win32 GetConsoleMode()错误代码6

[英]win32 GetConsoleMode() error code 6

I'm following the example from a another post here Reading a password from std::cin where you grab the handle to standard input, get the current console mode, change the mode to stifle echo on input. 我正在从另一篇文章中跟踪该示例,请从std :: cin读取密码,在该示例中,您将手柄抓住到标准输入,获取当前的控制台模式,将模式更改为抑制输入时的回显。 For some reason, when i call GetStdHandle() it returns a valid handle, but when I invoke GetConsoleMode() it fails and returns error code 6. I'm using this in a cmake project. 由于某种原因,当我调用GetStdHandle()时,它返回一个有效的句柄,但是当我调用GetConsoleMode()时,它失败并返回错误代码6。我在cmake项目中使用它。 Are there any debug flags I am supposed to set for this to work as intended? 我应该为此设置任何调试标志吗? Anyone else encountered this? 还有其他人遇到吗?

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;
    }
}

EDIT: reproduced with this code. 编辑:转载与此代码。

CMakeLists.txt CMakeLists.txt

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 main.cpp

#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 Studio 12. Invoke these in some directory. Visual Studio12。在某个目录中调用它们。 I get "Could not get console mode 6", implying GetLastError() returns 6. 我收到“无法获取控制台模式6”,这意味着GetLastError()返回6。

mkdir build
cmake ..
msbuild.exe tester.sln
./Debug/tester.exe

EDIT: It appears that this only fails when run from the command line. 编辑:看来这仅在从命令行运行时失败。 Within visual studio from the visual studio debugger, it succeeds. 在Visual Studio调试器的Visual Studio中,它成功了。 Still not enough knowledge of visual studio to determine what is going on. 仍然对Visual Studio缺乏足够的知识来确定正在发生的事情。 I just want to make a simple exe that can run from the command line and hide its input. 我只想制作一个可以从命令行运行并隐藏其输入的简单exe。

EDIT: cleanliness and also obtaining GetLastError asap after calls. 编辑:清洁度,并在调用后尽快获得GetLastError。 Still no change. 仍然没有变化。

This error 6 means "invalid handle" and means that the handle you have passed to GetConsoleMode is not a console handle. 错误6的意思是“无效的句柄”,并且意味着您传递给GetConsoleMode的句柄不是控制台句柄。 Ie the STDIN has been redirected from somewhere. 即STDIN已从某个地方重定向。

To ensure you have the handle to the current console, regardless of whether STDIN is redirected from somewhere else, use CreateFile with the special name "CONIN$" , which opens the console (if present). 为了确保您具有当前控制台的句柄,无论是否从其他地方重定向了STDIN,都可以使用具有特殊名称"CONIN$" CreateFile来打开控制台(如果存在)。

Example: 例:

HANDLE hConsole = CreateFile("CONIN$",  
    GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 
    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM