我在互联网上搜索了很多,但他们大多数都在谈论reindirect输出。没有人给出任何成功的reindirect输入示例。对于我下面的代码,当我运行命令“ipconfig”或“192.168.0.10”时,它会给出正确的输出,因为在运行这些命令后子进程结束,不需要输入。但是当我运行命令“ftp”而不是“ipconfig”时,控制台的子进程正在等待下一个输入命令。正如你所看到的,我试图在这种情况下将11111作为输入写入控制台。然而,控制台没有收到我的输入命令并永远等待输入命令。我怎样才能成功地应对这个计划“ftp”的命令,并保持控制台运行我怎样才能让createprocess reindirect输入成功,我已经成功地获得reindirect输出结果
#include <windows.h>
#include <fstream>
using namespace std;
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpComLine,
int nCmdShow)
{
SECURITY_ATTRIBUTES secAttr;
HANDLE hRead,hWrite;
char command[256];
char testBuf[256] = {0};
strcpy(command, "ipconfig");
// strcpy(command, "ping 192.168.0.10")
// strcpy(command, "ftp");
secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
secAttr.lpSecurityDescriptor = NULL;
secAttr.bInheritHandle = TRUE;
HANDLE hTxtFile = CreateFile("tmp.txt", GENERIC_ALL, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hTxtFile == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "Error createfile", NULL, MB_OK);
return 0;
}
HANDLE hWriteFile = CreateFile("Write.txt", GENERIC_WRITE, 0, &secAttr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hWriteFile == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "Error createWritefile", NULL, MB_OK);
return 0;
}
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
startupInfo.cb = sizeof(STARTUPINFO);
GetStartupInfo(&startupInfo);
startupInfo.hStdError = hTxtFile;
startupInfo.hStdOutput = hTxtFile;
startupInfo.hStdInput = hWriteFile;
startupInfo.wShowWindow = SW_SHOW;
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
char output[10240] = {0};
DWORD bytesRead;
if (!CreateProcess(NULL, command,NULL,NULL,TRUE,NULL,NULL,NULL,&startupInfo,&processInfo))
{
MessageBox(NULL, "Error createprocess", NULL, MB_OK);
CloseHandle(hWrite);
CloseHandle(hRead);
return FALSE;
}
DWORD processExitCode = 0;
strcpy(testBuf, "11111\r\n");
while (GetExitCodeProcess(processInfo.hProcess, &processExitCode))
{
WriteFile(hWriteFile, testBuf, 7, &bytesRead, NULL);
if (processExitCode != STILL_ACTIVE)
{
// MessageBox(NULL, "End process", NULL, MB_OK);
break;
}
Sleep(1000);
}
SetFilePointer(hTxtFile, NULL, NULL, FILE_BEGIN);
ReadFile(hTxtFile, output, 10240, &bytesRead, NULL);
CloseHandle(hTxtFile);
MessageBox(NULL, output, NULL, MB_OK);
return 0;
}
1)需要关闭句柄,你不做2)'hStdInput'必须有'FILE_GENERIC_READ'访问3)大多数程序时查看空输入('NumberOfBytesRead == 0'或* ZwReadFile *回报* STATUS_END_OF_FILE *)只需退出 - 所以你的代码将不会与文件系统文件一起工作。或者在创建进程之前需要将数据写入'hStdInput' *。 – RbMm
4)一般说明 - 在使用同步共享文件时使用它 - 不正确 - 文件共享* CurrentByteOffset *。当你调用* WriteFile *时,你可以不从你认为的位置写入,因为子进程可以改变位置(这可以避免在* OVERLAPPED *中使用直接偏移)。你的写改变* CurrentByteOffset *在共享文件对象,并影响子进程5)使用'processExitCode!= STILL_ACTIVE'不是100%可靠的方式 - 如果子调用ExitProcess(STILL_ACTIVE)'? – RbMm
我已经在我的项目中找到了问题,所以基本上在我们使用STARTF_USESTDHANDLES属性时。 createprocess将创建非交互式控制台,这意味着它只能在createprocess调用中运行一个命令行。任何想法我可以使用createprocess创建一个交互式重定向控制台,它根据最后的控制台输出接受用户输入?非常感谢 –