如何在同一过程中执行命令

时间:2020-04-05 17:53:09

标签: c++ cmd process pipe

我做了自己的函数来执行命令并保存结果。问题是命令只能执行一次,而我不能执行多个具有相同“上下文”的命令。例如。如果我执行cd ..,则我的cd ..的下一个命令将被忽略。这是我的代码:

std::string executeCommand(const std::string& cmd)
{
    system((cmd + " > temp.txt").c_str());
    std::ifstream ifs("temp.txt");
    std::string ret{ std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>() };
    ifs.close(); // must close the inout stream so the file can be cleaned up
    return ret;
}

我可以使用此功能的样品吗?

1 个答案:

答案 0 :(得分:2)

您使用Windows系统吗? 在Windows中,您可以通过管道与cmd进行交互。

像这样:

#define BUFFER_SIZE 131072 //128*1024‬
void work() {
    HANDLE hinRead, hinWrite, houtRead, houtWrite;

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = 0;
    sa.bInheritHandle = true;

    if (!CreatePipe(&hinRead, &hinWrite, &sa, 0)) {
        MessageBoxA(NULL, "Error CreatePipe", "Error", MB_ICONERROR);
    }
    if (!CreatePipe(&houtRead, &houtWrite, &sa, 0)) {
        MessageBoxA(NULL, "Error CreatePipe", "Error", MB_ICONERROR);
    }

    STARTUPINFOA si;
    ZeroMemory(&si, sizeof(si));
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = hinRead;//redirect Input
    si.hStdOutput = si.hStdError = houtWrite;//redirect Output

    PROCESS_INFORMATION ProcessInformation;
    char cmdLine[256] = { 0 };
    GetSystemDirectoryA(cmdLine, sizeof(cmdLine));
    strcat(cmdLine, ("\\cmd.exe"));
    if (CreateProcessA(cmdLine, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &ProcessInformation) == 0) {
        MessageBoxA(NULL, "Error CreateProcessA", "Error", MB_ICONERROR);
    }

    char* pbuff = new char[BUFFER_SIZE];
    DWORD dw;
    Sleep(100);//wait cmd start
    ReadFile(houtRead, pbuff, BUFFER_SIZE-1, &dw, NULL);
    pbuff[dw] = 0;
    printf(pbuff);//version info

    while (1) {
        char* p = pbuff;
        while ((*p = getchar()) != '\n') {
            ++p;
        }
        WriteFile(hinWrite, pbuff, p - pbuff + 1, &dw, 0);
        while (1) {
            ReadFile(houtRead, pbuff, BUFFER_SIZE - 1, &dw, NULL);
            pbuff[dw] = 0;
            printf("%s", pbuff);
            if (pbuff[dw - 1] == '>')break;
        }
    }
}

管道可以像文件一样读写。

在其他系统中,也有类似管道的东西,但是我对它们不熟悉。

编辑:另一个更清晰的示例

int main() {

    HANDLE hinRead, hinWrite, houtRead, houtWrite;

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = 0;
    sa.bInheritHandle = true;

    if (!CreatePipe(&hinRead, &hinWrite, &sa, 0)) {
        MessageBoxA(NULL, "Error CreatePipe", "Error", MB_ICONERROR);
    }
    if (!CreatePipe(&houtRead, &houtWrite, &sa, 0)) {
        MessageBoxA(NULL, "Error CreatePipe", "Error", MB_ICONERROR);
    }

    STARTUPINFOA si;
    ZeroMemory(&si, sizeof(si));
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;//no window
    si.hStdInput = hinRead;//redirect Input
    si.hStdOutput = si.hStdError = houtWrite;//redirect Output

    PROCESS_INFORMATION pi;
    char cmdLine[256] = { 0 };
    GetSystemDirectoryA(cmdLine, sizeof(cmdLine));
    strcat(cmdLine, ("\\cmd.exe"));
    if (CreateProcessA(cmdLine, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0) {
        MessageBoxA(NULL, "Error CreateProcessA", "Error", MB_ICONERROR);
    }

    Sleep(100);//wait cmd start

    char* pbuff = new char[1024 * 128];
    DWORD dw;

    ReadFile(houtRead, pbuff, 1024 * 128, &dw, NULL), pbuff[dw] = 0, printf("%s", pbuff);//cmd version info


    WriteFile(hinWrite, "cd ..\n", 6, &dw, NULL);//send command to cmd.exe

    Sleep(100);//wait command execute and cmd outputs
    ReadFile(houtRead, pbuff, 1024 * 128, &dw, NULL), pbuff[dw] = 0, printf("%s", pbuff);


    WriteFile(hinWrite, "dir\n", 4, &dw, NULL);//another command
    Sleep(100);
    ReadFile(houtRead, pbuff, 1024 * 128, &dw, NULL), pbuff[dw] = 0, printf("%s", pbuff);

    delete[] pbuff;
    TerminateProcess(pi.hProcess, 0);//Terminate cmd.exe
    return 0;
}
相关问题