【发布时间】:2017-04-28 23:09:35
【问题描述】:
对不起,我的英语不好,但我无法解决问题。现在我正在编写远程控制台。它使用 QTcpSocket 和函数与 Windows 控制台一起工作。几乎可以完美运行,但是当我尝试从控制台读取时,我需要先按 Enter,然后才会读取我的第一个字母。如果我想输入第二个字母,我需要再次按 Enter。我怎样才能读懂我写的每封信? 这是我的构造函数:
FreeConsole();
dwProcessId = 0 ;
dwErrorId = 0;
std::wstring path = L"cmd.exe";
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
SECURITY_ATTRIBUTES security = {
sizeof(security), NULL, TRUE
};
if(CreateProcess(NULL, (LPWSTR)path.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
dwProcessId = pi.dwProcessId;
}
else
{
dwErrorId = GetLastError();
printf("CreateProcess failed (%d).\n", dwErrorId);
return;
}
Sleep(1000);
if(!AttachConsole(pi.dwProcessId))
{
dwErrorId = GetLastError();
printf( "AttachConsole failed (%d).\n", dwErrorId);
return;
}
在这里我有问题的功能:
int Console::readInputFromConsole(DataIn& data)
{
data.inputRecords.resize(40);
HANDLE inputHandle = GetStdHandle(STD_INPUT_HANDLE);
DWORD events = 0;
DWORD unread = 0;
DWORD fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
//fdwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
BOOL bMode = SetConsoleMode(inputHandle, fdwMode);
if(!bMode)
{
std::runtime_error("error with mode");
}
Sleep(20);
BOOL statusUnread = TRUE;
statusUnread = GetNumberOfConsoleInputEvents(inputHandle, &unread);
if(!statusUnread)
throw std::runtime_error("GetNumberOfConsoleInputEvents failed.");
data.inputRecords.resize(unread);
BOOL statusRead = TRUE;
statusRead = ReadConsoleInput(inputHandle, &data.inputRecords[0], unread, &events);
if(!statusRead)
throw std::runtime_error("ReadConsoleInput failed.");
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &data.consoleScreenBufferInfo);
return 0;
}
【问题讨论】:
-
在阅读之前更改控制台模式无法正常工作,为时已晚。您必须在 main() 函数中更改它。对于您不拥有的控制台,这会打击执行此操作的选项。根本问题是您有 两个 进程试图从控制台读取。您的代码只会使第二个进程随机失败。没有简单的解决方案,您必须重新考虑这一点。
-
....你为什么还要从本地控制台读取输入?我不确定我是否理解您的情况。
-
我需要它来模拟控制台输入和输出。例如,我可以使用 far.exe,使用我的程序(显然在未来)。它必须如何在本地控制台工作,但在另一台计算机上执行命令。但我现在没有其他方法可以做到这一点,我的导师只向我展示了这种方式。
-
如果该程序在本地计算机上运行,从用户那里获取输入并(最终)将该输入传递给远程计算机以运行,您为什么要启动
cmd.exe的副本?cmd.exe进程打算做什么? -
是的,在客户端 cmd.exe 是不必要的,但在服务器端我需要执行我的命令:“dir”、“chcp”、“cd”或其他。为此,我创建了进程“cmd.exe”并在此进程中传递命令。在我读取所有输出并将其发送到客户端之后。