bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID, int timeoutMs)
{
    connection = nullptr;
    jassert (childProcess.kill());

    const String pipeName ("p" + String::toHexString (Random().nextInt64()));

    StringArray args;
    args.add (executable.getFullPathName());
    args.add (getCommandLinePrefix (commandLineUniqueID) + pipeName);

    if (childProcess.start (args))
    {
        connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs);

        if (connection->isConnected())
        {
            sendMessageToSlave (MemoryBlock (startMessage, specialMessageSize));
            return true;
        }

        connection = nullptr;
    }

    return false;
}
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID,
                                             int timeoutMs, int streamFlags)
{
    killSlaveProcess();

    auto pipeName = "p" + String::toHexString (Random().nextInt64());

    StringArray args;
    args.add (executable.getFullPathName());
    args.add (getCommandLinePrefix (commandLineUniqueID) + pipeName);

    childProcess.reset (new ChildProcess());

    if (childProcess->start (args, streamFlags))
    {
        connection.reset (new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs));

        if (connection->isConnected())
        {
            sendMessageToSlave ({ startMessage, specialMessageSize });
            return true;
        }

        connection.reset();
    }

    return false;
}
bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine,
                                                   const String& commandLineUniqueID)
{
    String prefix (getCommandLinePrefix (commandLineUniqueID));

    if (commandLine.trim().startsWith (prefix))
    {
        String pipeName (commandLine.fromFirstOccurrenceOf (prefix, false, false)
                                    .upToFirstOccurrenceOf (" ", false, false).trim());

        if (pipeName.isNotEmpty())
        {
            connection = new Connection (*this, pipeName);

            if (! connection->isConnected())
                connection = nullptr;
        }
    }

    return connection != nullptr;
}
bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine,
                                                   const String& commandLineUniqueID,
                                                   int timeoutMs)
{
    auto prefix = getCommandLinePrefix (commandLineUniqueID);

    if (commandLine.trim().startsWith (prefix))
    {
        auto pipeName = commandLine.fromFirstOccurrenceOf (prefix, false, false)
                                   .upToFirstOccurrenceOf (" ", false, false).trim();

        if (pipeName.isNotEmpty())
        {
            connection.reset (new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs));

            if (! connection->isConnected())
                connection.reset();
        }
    }

    return connection != nullptr;
}