我正在从另一篇文章中跟踪该示例,请从std :: cin中读取密码,在该示例中,您将手柄抓住到标准输入,获取当前的控制台模式,将模式更改为抑制输入时的回声。由于某种原因,当我调用GetStdHandle()时,它返回一个有效的句柄,但是当我调用GetConsoleMode()时,它失败并返回错误代码6。我在cmake项目中使用它。我应该为此设置任何调试标志吗?还有其他人遇到吗?
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
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
#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 Studio12。在某个目录中调用它们。我收到“无法获取控制台模式6”,这意味着GetLastError()返回6。
mkdir build
cmake ..
msbuild.exe tester.sln
./Debug/tester.exe
编辑:看来这仅在从命令行运行时失败。在Visual Studio调试器的Visual Studio中,它可以成功。仍然对Visual Studio缺乏足够的知识来确定发生了什么。我只想制作一个可以从命令行运行并隐藏其输入的简单exe。
编辑:清洁度,并在调用后也尽快获取GetLastError。仍然没有变化。
错误6的意思是“无效的句柄”,并且意味着您传递给的句柄GetConsoleMode
不是控制台句柄。即STDIN已从某个地方重定向。
为确保您具有当前控制台的句柄,无论STDIN是否从其他地方重定向,都应使用CreateFile
特殊名称"CONIN$"
,这将打开控制台(如果存在)。
例子:
HANDLE hConsole = CreateFile("CONIN$",
GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句