所以我想修改由微軟(here)提供的代碼使用WriteConsoleInput,而不是WriteFile的,但它說的句柄無效(我打賭這是什麼真的很傻),怎麼樣手柄最初創建或者其他的東西。爲什麼一個HANDLE不適用於WriteConsoleInput,但適用於WriteFile?
所以我的問題,什麼是和WriteFile的手柄需要WriteConsoleInput手柄之間的區別,?
我猜測它有與由CreateProcess的/ CreatePipe/DuplicateHandle過程中創建的繼承手柄通過的CreateFile創建的句柄的權限標誌做。
我決定這將是更容易,如果你能看到的問題,所以這是我的完整的解決方案(使用Visual Studio 2012)兩個孩子和家長的應用程序都包括在內。
作爲一個說明,我需要的是兒童應用使用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;
}
認爲一個句柄作爲一個指向一個結構。指針只是一個指針,但是一個結構與另一個結構不可比。 – Twifty
這是我的第一個處理不只是將文件保存到磁盤的項目,所以你所說的話告訴我,我得到一個「無效的句柄」,因爲它不是一個CONSOLE輸入句柄,它只是一個句柄STDIN。不是一回事。是對的嗎? –