Пример #1
0
    static HANDLE createProcess(const String& win32ProgramFileName,
                                const String& commandLine,
                                EnvMap::Ptr   environmentMap = Null,
                                HANDLE*       inputHandle    = NULL,
                                HANDLE*       outputHandle   = NULL,
                                HANDLE*       stderrHandle   = NULL)
    {
        STARTUPINFO         su;
        memset(&su, 0, sizeof(su));
        su.cb = sizeof(su);

        bool useHandles = (    inputHandle != NULL 
                           && outputHandle != NULL 
                           && stderrHandle != NULL);

        HANDLE stdinRead,  stdinWrite;
        HANDLE stdoutRead, stdoutWrite;
        HANDLE stderrRead, stderrWrite;
        
        if (useHandles)
        {
            createPipeForCreatedProcess(&stdinRead,  &stdinWrite);
            createPipeForCreatedProcess(&stdoutRead, &stdoutWrite);
            createPipeForCreatedProcess(&stderrRead, &stderrWrite);
            
            setInheritFlag(stdinRead);
            setInheritFlag(stdoutWrite);
            setInheritFlag(stderrWrite);

            *inputHandle  = stdinWrite;
            *outputHandle = stdoutRead;
            *stderrHandle = stderrRead;

            su.hStdInput  = stdinRead;
            su.hStdOutput = stdoutWrite;
            su.hStdError  = stderrWrite;
            su.dwFlags |= STARTF_USESTDHANDLES;
        }

        PROCESS_INFORMATION pi;
        memset(&pi, 0, sizeof(pi));
        
        CharArray commandLineBuffer;
                  commandLineBuffer.appendString(commandLine);
                  commandLineBuffer.append('\0');
        
        {
            char*      environmentStringsPtr = NULL;
            CharArray  environmentStrings;
            if (environmentMap.isValid()) {
                environmentStrings.appendString(buildEnvironmentStringsFromMap(environmentMap));
                environmentStringsPtr = environmentStrings.getPtr();
            }
            const bool inheritHandles = useHandles;
            
            bool wasOK = CreateProcess(win32ProgramFileName.toCString(),   // lpApplicationName
                                       commandLineBuffer.getPtr(),    // lpCommandLine
                                       0,         // lpProcessAttributes,
                                       0,         // lpThreadAttributes,
                                       inheritHandles,      // bInheritHandles,
                                       DETACHED_PROCESS|HIGH_PRIORITY_CLASS, // dwCreationFlags,
                                       environmentStringsPtr,      // lpEnvironment,
                                       NULL,      // lpCurrentDirectory,
                                       &su,         // in:  lpStartupInfo,
                                       &pi);        // out: lpProcessInformation
    
            if (!wasOK)
            {
                throw SystemException(String() << "Error in call to Win32 CreateProcess for '" << win32ProgramFileName << "'");
            }
        }
        if (useHandles) {
            CloseHandle(stdinRead);
            CloseHandle(stdoutWrite);
            CloseHandle(stderrWrite);
        }
        CloseHandle(pi.hThread);        
        
        return pi.hProcess;
    }