创建进程

CreateProcess 函数创建独立于创建进程运行的新进程。 为简单起见,此关系称为父子关系。

Important

安全性—句柄继承:将 bInheritHandles 设为 FALSE,除非子进程明确需要访问继承的句柄。 继承的句柄(文件句柄、套接字、令牌)可能会将敏感资源泄漏给子进程。 当需要继承时,使用 STARTUPINFOEXUpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_HANDLE_LIST, ...) 显式列出子进程需要的句柄。

Important

lpCommandLine 必须可写:将命令行作为 lpCommandLine 参数(第二个参数)传递时,缓冲区 必须是可写字符数组 ,而不是字符串文本或 const 指针。 Unicode 版本 (CreateProcessW) 可以就地修改此缓冲区。 传递只读字符串会导致访问冲突。

注释

新式替代方法:对于更简单的进程创建方案,请考虑 System.Diagnostics.Process(.NET)、 _wspawnl/_wsystem (CRT)或 ShellExecuteEx(用于启动具有谓词处理的文档/URL)。 需要完全控制处理继承、进程属性、安全描述符或创建标志时使用 CreateProcess

以下代码演示如何创建进程。

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

void _tmain( int argc, TCHAR *argv[] )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    if( argc != 2 )
    {
        printf("Usage: %s [cmdline]\n", argv[0]);
        return;
    }

    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        argv[1],        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}

如果 CreateProcess 成功,它将返回一个 PROCESS_INFORMATION 结构,其中包含新进程及其主线程的句柄和标识符。 线程和进程句柄是使用完全访问权限创建的,不过,如果指定安全描述符,则可以限制访问。 如果不再需要这些句柄,请使用 CloseHandle 函数关闭它们。

还可以使用 CreateProcessAsUserCreateProcessWithLogonW 函数来创建进程。 这些函数允许你指定运行进程的用户帐户的安全上下文。