C++ Win32:如何 运行 在新控制台中使用 CreateProcessA() 传输客户端可执行文件 window

C++ Win32: How to run pipe client executable with CreateProcessA() in a new console window

在我的项目中,我有两个应用程序,一个是 Pipe Server 和 Pipe Client(Slave)。 我正在尝试通过管道发送文本以将其显示在客户端的控制台上。从而有效地创建一次性游戏机。

我已经通过手动 运行 测试了代码,首先是服务器,然后是客户端。它运行完美。然后我在 Server 的构造函数中添加了一些代码以使用管道名作为参数调用 Slave.exe 但是 Slave 的控制台在几秒钟后消失了。 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;
}

现在我需要服务器的控制台和客户端的控制台都保持打开状态以进行进一步测试,但是当服务器等待从服务器连接到管道时,从服务器的控制台和进程关闭,这不应该发生,因为我之前已经暂停了它它可以 return.

编辑:管道客户端对象构造函数:

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

Class 字段:

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

Github 回购:https://github.com/BhayanakMoth2/PipedConsole

所以我解决了问题,我没有正确使用 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() 中的第二个参数通过正确传递参数解决了这个问题。