gpt4 book ai didi

c++ - 为什么一个 HANDLE 不适用于 WriteConsoleInput,但适用于 WriteFile?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:49:48 25 4
gpt4 key购买 nike

所以我试图修改 Microsoft ( here ) 提供的代码以使用 WriteConsoleInput,而不是 WriteFile,但它说句柄无效(我敢打赌这真的很愚蠢),比如句柄如何最初是创建的或其他东西。

那么我的问题是,WriteConsoleInput 所需的句柄与 WriteFile 所需的句柄之间有什么区别?

WriteConsoleInput

WriteFile

与 CreateProcess/CreatePipe/DuplicateHandle 进程创建的继承句柄相比,我猜它与 CreateFile 创建的 HANDLE 的权限标志有关。

我认为如果您能看到问题会更容易,所以这里是我的完整解决方案(使用 Visual Studio 2012)包括子应用程序和父应用程序。

ConsoleRedir on GitHub

请注意,我需要子应用程序才能使用 ReadConsoleInput,这一直是我沮丧的根源。

原始方法:

/////////////////////////////////////////////////////////////////////// 
// GetAndSendInputThreadOrig
// Thread procedure that monitors the console for input and sends input
// to the child process through the input pipe.
// This thread ends when the child application exits.
// Original from http://support.microsoft.com/kb/190351
///////////////////////////////////////////////////////////////////////
DWORD WINAPI GetAndSendInputThreadOrig(LPVOID lpvThreadParam)
{
CHAR read_buff[256];
DWORD nBytesRead,nBytesWrote;
HANDLE hPipeWrite = (HANDLE)lpvThreadParam;

// Get input from our console and send it to child through the pipe.
while (bRunThread)
{
if(!ReadConsole(hStdIn,read_buff,1,&nBytesRead,NULL))
DisplayError("ReadConsole");

read_buff[nBytesRead] = '\0'; // Follow input with a NULL.

if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&nBytesWrote,NULL))
{
if (GetLastError() == ERROR_NO_DATA)
break; // Pipe was closed (normal exit path).
else
DisplayError("WriteFile");
}
}

return 1;
}

我的修改版本(必须构建击键):

/////////////////////////////////////////////////////////////////////// 
// GetAndSendInputThread
// Thread procedure that monitors the console for input and sends input
// to the child process through the input pipe.
// This thread ends when the child application exits.
///////////////////////////////////////////////////////////////////////
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
{
CHAR read_buff[256];
DWORD nBytesWrote;
HANDLE hPipeWrite = (HANDLE)lpvThreadParam;

// Get input from our console and send it to child through the pipe.
while (bRunThread)
{
INPUT_RECORD inputRecords[4];
// Build a keyboard event, press '?' and then press RETURN
inputRecords[0].EventType = KEY_EVENT;
inputRecords[0].Event.KeyEvent.bKeyDown = TRUE;
inputRecords[0].Event.KeyEvent.uChar.UnicodeChar = '?';
inputRecords[1].EventType = KEY_EVENT;
inputRecords[1].Event.KeyEvent.bKeyDown = FALSE;
inputRecords[1].Event.KeyEvent.uChar.UnicodeChar = '?';
inputRecords[2].EventType = KEY_EVENT;
inputRecords[2].Event.KeyEvent.bKeyDown = TRUE;
inputRecords[2].Event.KeyEvent.dwControlKeyState = 0;
inputRecords[2].Event.KeyEvent.uChar.UnicodeChar = '\r';
inputRecords[2].Event.KeyEvent.wRepeatCount = 1;
inputRecords[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
inputRecords[2].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
inputRecords[3].EventType = KEY_EVENT;
inputRecords[3].Event.KeyEvent.bKeyDown = FALSE;
inputRecords[3].Event.KeyEvent.dwControlKeyState = 0;
inputRecords[3].Event.KeyEvent.uChar.UnicodeChar = '\r';
inputRecords[3].Event.KeyEvent.wRepeatCount = 1;
inputRecords[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
inputRecords[3].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);


if (!WriteConsoleInput(hPipeWrite,inputRecords,sizeof(inputRecords) / sizeof(*inputRecords),&nBytesWrote))
{
if (GetLastError() == ERROR_NO_DATA)
break; // Pipe was closed (normal exit path).
else
DisplayError("WriteConsoleInput");
}
}

return 1;
}

最佳答案

WriteConsoleInput 要求句柄是“控制台输入缓冲区的句柄”。 (您问题中链接页面中 handle 输入参数描述中的第一句话)。

您需要使用 GetStdHandle 中的句柄以获得合适的 handle 。

WriteConsoleInput 仅适用于控制台的直接句柄,不适用于重定向管道或类似设备。

关于c++ - 为什么一个 HANDLE 不适用于 WriteConsoleInput,但适用于 WriteFile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17650336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com