Как выполнять команды в одном процессе - PullRequest
1 голос
/ 05 апреля 2020

Я сделал свою собственную функцию для выполнения команды и сохранения результата. Проблема в том, что команда выполняется один раз, и я не могу выполнить несколько команд с одинаковым «контекстом». Например. Если я выполню cd .., следующая команда my 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 Ответ

2 голосов
/ 06 апреля 2020

Используете ли вы Windows system? В 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;
        }
    }
}

Канал может читать / писать как file.

В других системах также есть что-то вроде pipe ,, но я не знаком с ними.

edit: еще один более понятный пример

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;
}
...