C ++ Win32: как запустить исполняемый файл pipe клиента с CreateProcessA () в новом окне консоли - PullRequest
0 голосов
/ 21 октября 2018

В моем проекте у меня есть два приложения, одно из которых - это Pipe Server и Pipe Client (Slave).Я пытаюсь отправить текст через канал, чтобы отобразить его на консоли клиента.Таким образом, эффективно создавая одноразовые консоли.

Я проверил код, запустив сначала сервер, а затем клиента.Работает отлично.Затем я добавил код в конструктор сервера, чтобы вызвать Slave.exe с pipename в качестве аргументов, однако консоль Slave исчезает через пару секунд.Ведущий конструктор вызывает эту функцию:

int OpenNamedPipe(std::string pipename)
{

    pipeurl += pipename;
    hPipe = CreateNamedPipe(
        pipeurl .c_str(),                            // pipe name 
        PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,   // read/write access 
        PIPE_TYPE_BYTE |                             // Datatype Byte
        PIPE_WAIT,                                   // blocking mode 
        1,                                           // max. instances  
        outputBuffer,                                // output buffer size 
        inputBuffer,                                 // input buffer size 
        0,                                  // client time-out 
        NULL);                             // default security attribute 

    if (hPipe == INVALID_HANDLE_VALUE)
    {
        try
        {
            Throw_Last_Error("CreateNamedPipe failed");
        }
        catch (const std::runtime_error err)
        {
            std::cout << "Runtime Error: " << err.what();
            return 0;
        }
    }
    int timeout = 100000;


    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(pi));
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    int retnVal = CreateProcessA("Slave.exe", (LPSTR)pipename.c_str(), NULL, NULL, NULL, DETACHED_PROCESS, NULL, NULL, &si, &pi);
    if (!retnVal)
    {
        retnVal = GetLastError();
    }
    if (!ConnectNamedPipe(hPipe, NULL))
    {
        if (!GetLastError() == ERROR_PIPE_CONNECTED)
        {
            try
            {
                Throw_Last_Error("Error while connecting to named pipe.");
            }
            catch (std::runtime_error err)
            {
                std::cout << "GLE= " << GetLastError();
                Block();
                return 0;
            }
        }
    }

    std::cout << "Connected to pipe.\n";
    return 0;
}

В основной программе клиента:

int main(int argc, char *argv[])
{
    AllocConsole();
    std::string argstr = " ";
    argstr = argv[1];
    PipeClient pc(argstr);
    pc.Update();
    system("pause");
    return 0;
}

Теперь мне нужно, чтобы и консоль сервера, и консоль клиента оставались открытыми для дальнейшего тестирования, но когда сервер ждетSlave для подключения к каналу, консоль Slave и процесс закрываются, что не должно произойти, поскольку я приостановил его, прежде чем он сможет вернуться.

Редактировать: Конструктор объекта Pipe Client:

PipeClient(std::string pipename)
{
    pipeName = pipeName + pipename;
    Connect();
    if (hPipe != INVALID_HANDLE_VALUE || GetLastError() != ERROR_PIPE_BUSY)
    {
        std::cout << "Created Pipe, GLE=" << GetLastError();

    }
    if (hPipe == INVALID_HANDLE_VALUE)
    {
        ThrowLastError("Failed to connect to named pipe.");
    }
}
int Connect()
{
    while (true)
    {
        WaitNamedPipeA(pipeName.c_str(), NMPWAIT_WAIT_FOREVER);
        hPipe = CreateFileA(
            pipeName.c_str(),
            GENERIC_READ |
            GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            0,
            NULL
        );
        if (hPipe != INVALID_HANDLE_VALUE || GetLastError() != ERROR_PIPE_BUSY)
        {
            std::cout << "Created Pipe, GLE=" << GetLastError();
            break;
        }
    }
    return 0;
}

Поля класса:

DWORD inputBuffer = 256;
DWORD outputBuffer = 256;
HANDLE hPipe;
std::string pipeName = "\\\\.\\pipe\\";
char * testpipename = "\\\\.\\pipe\\namedpipe";

Репозиторий Github: https://github.com/BhayanakMoth2/PipedConsole

1 Ответ

0 голосов
/ 22 октября 2018

Итак, я исправил проблему, я не использовал функцию CreateProcess должным образом.

Это должен быть фиксированный вызов функции:

std::string cmd = "Slave.exe " + pipename;
    int retnVal = CreateProcessA("Slave.exe", (LPSTR)cmd.c_str(), NULL, NULL, NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

Я неправильно прочитал документацию.И причина сбоя Slave.exe в том, что аргументы не были переданы должным образом, и поэтому, когда он достиг:

 argstr = argv[1]

, он молча зависал.Второй аргумент в CreateProcessA () решает эту проблему путем правильной передачи аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...