我想要通过管道通信控制CMD,能从父进程读数据就是写不了,WriteFile后没反应,szCOMMAND改成随便一个DOS命令,就是没反应,没辙了,请问代码什么地方出了问题呢?
SECURITY_ATTRIBUTES sa;
SECURITY_ATTRIBUTES sa1;
HANDLE hRead_A, hWrite_A;
HANDLE hRead_B, hWrite_B;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
sa1.bInheritHandle = TRUE;
sa1.lpSecurityDescriptor = NULL;
sa1.nLength = sizeof(sa1);
if (!CreatePipe(&hRead_A, &hWrite_A, &sa, 0)) {
printf("ERROR,createpipe_1");
}
if (!CreatePipe(&hRead_B, &hWrite_B, &sa1, 0)){
printf("ERROR,createpipe_2");
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdInput = hRead_A;
si.hStdError = hWrite_B;
si.hStdOutput = hWrite_B;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, TEXT("cmd")
, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
printf("createprocess %d",GetLastError());
}
char buffer[4096] = { 0 };
DWORD bytesRead;
while (true) {
DWORD dwdw;
WriteFile(hWrite_A,szCOMMAND , sizeof(szCOMMAND), &dwdw, NULL);
if (ReadFile(hRead_B, buffer, 4095, &bytesRead, NULL) == NULL)
break;
printf(buffer);
}

这个是把szCOMMAND改成ping命令的,运行后没反应

该回答引用ChatGPT-3.5,仅供参考,不保证完全正确
根据你提供的代码和描述,可能出现了以下几个问题:
写入管道的命令长度不正确:在 WriteFile
函数中,你使用了 sizeof(szCOMMAND)
来指定写入的字节数,但是 szCOMMAND
可能是一个指针,因此 sizeof(szCOMMAND)
得到的是指针的大小,而不是字符串的长度。你应该使用一个正确的长度来替代 sizeof(szCOMMAND)
,比如使用 strlen(szCOMMAND)
来获取字符串的实际长度。
读取命令输出的方式不正确:在代码中,你将标准输出和标准错误都重定向到了 hWrite_B
,然后在循环中通过读取 hRead_B
来获取命令的输出。然而,标准输出和标准错误是分开的流,因此你需要分别读取它们的数据。你可以使用两个不同的缓冲区来分别读取标准输出和标准错误的数据。
以下是修改后的代码,修复了上述问题:
SECURITY_ATTRIBUTES sa;
SECURITY_ATTRIBUTES sa1;
HANDLE hRead_A, hWrite_A;
HANDLE hRead_B, hWrite_B;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
sa1.bInheritHandle = TRUE;
sa1.lpSecurityDescriptor = NULL;
sa1.nLength = sizeof(sa1);
if (!CreatePipe(&hRead_A, &hWrite_A, &sa, 0)) {
printf("ERROR,createpipe_1");
}
if (!CreatePipe(&hRead_B, &hWrite_B, &sa1, 0)) {
printf("ERROR,createpipe_2");
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdInput = hRead_A;
si.hStdError = hWrite_B;
si.hStdOutput = hWrite_B;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL, TEXT("cmd"), NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi)) {
printf("createprocess %d", GetLastError());
}
char bufferOut[4096] = { 0 }; // 用于读取标准输出的缓冲区
char bufferErr[4096] = { 0 }; // 用于读取标准错误的缓冲区
DWORD bytesReadOut, bytesReadErr;
while (true) {
DWORD dwdw;
char szCOMMAND[] = "ping 127.0.0.1"; // 用于写入管道的命令
WriteFile(hWrite_A, szCOMMAND, strlen(szCOMMAND), &dwdw, NULL);
// 读取标准输出
if (ReadFile(hRead_B, bufferOut, sizeof(bufferOut) - 1, &bytesReadOut, NULL) && bytesReadOut > 0) {
bufferOut[bytesReadOut] = '\0'; // 添加字符串结束符
printf("Standard Output: %s\n", bufferOut);
}
// 读取标准错误
if (ReadFile(hWrite
_B, bufferErr, sizeof(bufferErr) - 1, &bytesReadErr, NULL) && bytesReadErr > 0) {
bufferErr[bytesReadErr] = '\0'; // 添加字符串结束符
printf("Standard Error: %s\n", bufferErr);
}
}
请注意,修改后的代码中使用了两个缓冲区 bufferOut
和 bufferErr
分别读取标准输出和标准错误的数据。另外,szCOMMAND
被修改为 "ping 127.0.0.1"
,这是一个示例命令,你可以根据需要更改为其他命令。