【发布时间】:2020-05-24 18:30:13
【问题描述】:
我有一个 WSASocket,当连接调用 CreateProcess 和服务器 cmd.exe 时,我想在进程 hStdInput 和套接字句柄之间实现一个管道来解析通过套接字发送的命令,一切似乎都运行顺利,除了因为当我运行像“ping 127.0.0.1”这样的命令并且必须等待输出时,在我通过套接字发送更多数据之前什么都没有显示,看来我的 ReadFile 调用正在阻止 hStdOut 处理程序发送任何内容。有没有什么办法解决这一问题?请不要被我的代码冒犯我正在编写这个项目作为学习练习,任何帮助将不胜感激。
int syncShell(SOCKET *ConnectSocket) {
int iResult = 0;
printf("Spawning process\n");
char Process[] = "C:\\Windows\\System32\\cmd.exe";
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
sinfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
// create pipe for external commands
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE hReadPipe = NULL, hWritePipe = NULL;
iResult = CreatePipe(&hReadPipe, &hWritePipe, &saAttr, DEFAULT_BUFLEN);
if (iResult == 0) {
printf("Pipe Error");
}
sinfo.hStdOutput = sinfo.hStdError = (HANDLE) *ConnectSocket;
sinfo.hStdInput = hReadPipe;
if (!CreateProcessA(NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo)) {
printf("CreateProcess failed (%d).\n", GetLastError());
}
// implement pipe logic
char buf[DEFAULT_BUFLEN];
DWORD len = 0;
WSABUF DataBuf;
while (1) {
// causing the block?
iResult = ReadFile((HANDLE) *ConnectSocket, buf, DEFAULT_BUFLEN, &len, NULL);
if (iResult == 0) {
printf("File Error or non-blocking");
}
else {
printf("%d: %.*s\n", len, len, buf);
WriteFile(hWritePipe, buf, len, NULL, NULL);
}
Sleep(1000);
}
WaitForSingleObject(pinfo.hProcess, INFINITE); // waits till proc finishes
CloseHandle(pinfo.hProcess);
CloseHandle(pinfo.hThread);
printf("Process exited\n");
return 0;
}
【问题讨论】:
-
如果您只是在两次读取之间睡觉,那么使用非阻塞 I/O 完全没有意义。你最好屏蔽掉。
-
我把它作为占位符放在那里,即使它不存在,但它仍然会阻止 hStdOut。
-
难以理解。为什么要将进程自己的输出写回它也是一个持续的谜。
-
感谢您的关注 207,在原始帖子中我提到我将通过管道解析命令。为简单起见,我忽略了这一点,这可能会让一些人感到困惑......
-
让除了你之外的所有人都感到困惑。