Compartilhar via


Função CreateProcessA (processthreadsapi.h)

Cria um novo processo e seu thread primário. O novo processo é executado no contexto de segurança do processo de chamada.

Se o processo de chamada estiver representando outro usuário, o novo processo usará o token para o processo de chamada, não o token de representação. Para executar o novo processo no contexto de segurança do usuário representado pelo token de representação, use a função CreateProcessAsUserA ou função CreateProcessWithLogonW.

Sintaxe

BOOL CreateProcessA(
  [in, optional]      LPCSTR                lpApplicationName,
  [in, out, optional] LPSTR                 lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCSTR                lpCurrentDirectory,
  [in]                LPSTARTUPINFOA        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

Parâmetros

[in, optional] lpApplicationName

O nome do módulo a ser executado. Este módulo pode ser um aplicativo baseado no Windows. Pode ser algum outro tipo de módulo (por exemplo, MS-DOS ou SO/2) se o subsistema apropriado estiver disponível no computador local.

A cadeia de caracteres pode especificar o caminho completo e o nome do arquivo do módulo a ser executado ou pode especificar um nome parcial. No caso de um nome parcial, a função usa a unidade atual e o diretório atual para concluir a especificação. A função não usará o caminho de pesquisa. Esse parâmetro deve incluir a extensão de nome de arquivo; nenhuma extensão padrão é assumida.

O parâmetro lpApplicationName pode ser NULL. Nesse caso, o nome do módulo deve ser o primeiro token delimitado por espaço em branco na cadeia de caracteres lpCommandLine . Se você estiver usando um nome de arquivo longo que contenha um espaço, use as cadeias de caracteres entre aspas para indicar onde o nome do arquivo termina e os argumentos começam; caso contrário, o nome do arquivo é ambíguo. Por exemplo, considere a cadeia de caracteres "c:\program files\sub dir\program name". Essa cadeia de caracteres pode ser interpretada de várias maneiras. O sistema tenta interpretar as possibilidades na seguinte ordem:

  1. c:\program.exe
  2. c:\program files\sub.exe
  3. c:\program files\sub dir\program.exe
  4. c:\program files\sub dir\program name.exe

Se o módulo executável for um aplicativo de 16 bits, lpApplicationName deverá ser NULL e a cadeia de caracteres apontada por lpCommandLine deverá especificar o módulo executável, bem como seus argumentos.

Para executar um arquivo em lote, você deve iniciar o interpretador de comando; defina lpApplicationName para cmd.exe e defina lpCommandLine para os seguintes argumentos: /c mais o nome do arquivo em lote.

Importante

A equipe de engenharia do MSRC aconselha contra isso. Consulte MS14-019 – Corrigindo um sequestro binário por meio de .cmd ou .bat de arquivo para obter mais detalhes.

[in, out, optional] lpCommandLine

A linha de comando a ser executada.

O comprimento máximo dessa cadeia de caracteres é de 32.767 caracteres, incluindo o caractere nulo de terminação Unicode. Se lpApplicationName for NULL, a parte do nome do módulo lpCommandLine será limitada a MAX_PATH caracteres.

A versão Unicode dessa função, CreateProcessW, pode modificar o conteúdo dessa cadeia de caracteres. Portanto, esse parâmetro não pode ser um ponteiro para memória somente leitura (como um const variável ou uma cadeia de caracteres literal). Se esse parâmetro for uma cadeia de caracteres constante, a função poderá causar uma violação de acesso.

O parâmetro lpCommandLine pode ser NULL. Nesse caso, a função usa a cadeia de caracteres apontada por lpApplicationName como a linha de comando.

Se lpApplicationName e lpCommandLine não foremNULL, a cadeia de caracteres terminada em nulo apontada por lpApplicationName especifica o módulo a ser executado e a cadeia de caracteres terminada em nulo apontada por lpCommandLine especificar a linha de comando. O novo processo pode usar GetCommandLine para recuperar toda a linha de comando. Os processos de console escritos em C podem usar os argumentos argc e argv para analisar a linha de comando. Como argv[0] é o nome do módulo, os programadores C geralmente repetem o nome do módulo como o primeiro token na linha de comando.

Se lpApplicationName for NULL, o primeiro token delimitado por espaço em branco da linha de comando especifica o nome do módulo. Se você estiver usando um nome de arquivo longo que contenha um espaço, use as cadeias de caracteres entre aspas para indicar onde o nome do arquivo termina e os argumentos começam (consulte a explicação para o parâmetro lpApplicationName). Se o nome do arquivo não contiver uma extensão, .exe será acrescentado. Portanto, se a extensão de nome de arquivo for .com, esse parâmetro deverá incluir a extensão .com. Se o nome do arquivo terminar em um período (.) sem extensão ou se o nome do arquivo contiver um caminho, .exe não será acrescentado. Se o nome do arquivo não contiver um caminho de diretório, o sistema procurará o arquivo executável na seguinte sequência:

  • O diretório do qual o aplicativo foi carregado.
  • O diretório atual para o processo pai.
  • O diretório do sistema Windows de 32 bits. Use a função GetSystemDirectoryA função para obter o caminho desse diretório.
  • O diretório do sistema Windows de 16 bits. Não há nenhuma função que obtenha o caminho desse diretório, mas ela é pesquisada. O nome desse diretório é System.
  • O diretório do Windows. Use a função GetWindowsDirectoryA para obter o caminho desse diretório.
  • Os diretórios listados na variável de ambiente PATH. Observe que essa função não pesquisa o caminho por aplicativo especificado pelo Caminhos do Aplicativo chave do Registro. Para incluir esse caminho por aplicativo na sequência de pesquisa, use a função ShellExecute.

O sistema adiciona um caractere nulo de terminação à cadeia de caracteres de linha de comando para separar o nome do arquivo dos argumentos. Isso divide a cadeia de caracteres original em duas cadeias de caracteres para processamento interno.

[in, optional] lpProcessAttributes

Um ponteiro para uma estrutura de SECURITY_ATTRIBUTES que determina se o identificador retornado para o novo objeto de processo pode ser herdado por processos filho. Se lpProcessAttributes for NULL, o identificador não poderá ser herdado.

O lpSecurityDescriptor membro da estrutura especifica um descritor de segurança para o novo processo. Se lpProcessAttributes for NULL ou lpSecurityDescriptor for NULL, o processo obterá um descritor de segurança padrão. As ACLs no descritor de segurança padrão para um processo vêm do token primário do criador. Windows XP: as ACLs no descritor de segurança padrão para um processo vêm do token principal ou de representação do criador. Esse comportamento mudou com o Windows XP com SP2 e Windows Server 2003.

[in, optional] lpThreadAttributes

Um ponteiro para uma estrutura de SECURITY_ATTRIBUTES que determina se o identificador retornado para o novo objeto de thread pode ser herdado por processos filho. Se lpThreadAttributes for NULL, o identificador não poderá ser herdado.

O lpSecurityDescriptor membro da estrutura especifica um descritor de segurança para o thread principal. Se lpThreadAttributes for NULL ou lpSecurityDescriptor for NULL, o thread obterá um descritor de segurança padrão. As ACLs no descritor de segurança padrão para um thread vêm do token de processo. Windows XP: as ACLs no descritor de segurança padrão para um thread vêm do token principal ou de representação do criador. Esse comportamento mudou com o Windows XP com SP2 e Windows Server 2003.

[in] bInheritHandles

Se esse parâmetro for TRUE, cada identificador herdável no processo de chamada será herdado pelo novo processo. Se o parâmetro for FALSE, as alças não serão herdadas. Observe que as alças herdadas têm o mesmo valor e direitos de acesso que os identificadores originais. Para obter discussões adicionais sobre identificadores herdáveis, consulte Comentários.

Serviços de Terminal: Você não pode herdar identificadores entre sessões. Além disso, se esse parâmetro for TRUE, você deverá criar o processo na mesma sessão que o chamador.

processos de PPL (Protected Process Light): A herança de identificador genérico é bloqueada quando um processo PPL cria um processo não PPL, uma vez que PROCESS_DUP_HANDLE não é permitido de um processo não PPL para um processo PPL. Consulte de Direitos de Acesso e Segurança do Processo

Windows 7: STD_INPUT_HANDLE, STD_OUTPUT_HANDLE e STD_ERROR_HANDLE são herdados, mesmo quando o parâmetro é FALSE.

[in] dwCreationFlags

Os sinalizadores que controlam a classe de prioridade e a criação do processo. Para obter uma lista de valores, consulte sinalizadores de criação de processo.

Esse parâmetro também controla a classe de prioridade do novo processo, que é usada para determinar as prioridades de agendamento dos threads do processo. Para obter uma lista de valores, consulte GetPriorityClass. Se nenhum dos sinalizadores de classe de prioridade for especificado, a classe de prioridade será NORMAL_PRIORITY_CLASS, a menos que a classe de prioridade do processo de criação seja IDLE_PRIORITY_CLASS ou BELOW_NORMAL_PRIORITY_CLASS. Nesse caso, o processo filho recebe a classe de prioridade padrão do processo de chamada.

Se o parâmetro dwCreationFlags tiver um valor de 0:

  • O processo herda o modo de erro do chamador e do console do pai.
  • Supõe-se que o bloco de ambiente do novo processo contenha caracteres ANSI (consulte lpEnvironment parâmetro para obter informações adicionais).
  • Um aplicativo baseado no Windows de 16 bits é executado em uma VDM (máquina virtual dos DOS) compartilhada.

[in, optional] lpEnvironment

Um ponteiro para o bloco de ambiente para o novo processo. Se esse parâmetro for NULL, o novo processo usará o ambiente do processo de chamada.

Um bloco de ambiente consiste em um bloco encerrado em nulo de cadeias de caracteres terminadas em nulo. Cada cadeia de caracteres está na seguinte forma:

nome=valor\0

Como o sinal de igual é usado como separador, ele não deve ser usado no nome de uma variável de ambiente.

Um bloco de ambiente pode conter caracteres Unicode ou ANSI. Se o bloco de ambiente apontado por lpEnvironment contiver caracteres Unicode, certifique-se de que dwCreationFlags inclua CREATE_UNICODE_ENVIRONMENT.

A versão ANSI dessa função, CreateProcessA falhar se o tamanho total do bloco de ambiente do processo exceder 32.767 caracteres.

Observe que um bloco de ambiente ANSI é encerrado por dois bytes zero: um para a última cadeia de caracteres, mais um para encerrar o bloco. Um bloco de ambiente Unicode é encerrado por quatro bytes zero: dois para a última cadeia de caracteres, mais dois para encerrar o bloco.

[in, optional] lpCurrentDirectory

O caminho completo para o diretório atual do processo. A cadeia de caracteres também pode especificar um caminho UNC.

Se esse parâmetro for NULL, o novo processo terá a mesma unidade e diretório atuais que o processo de chamada. (Esse recurso é fornecido principalmente para shells que precisam iniciar um aplicativo e especificar sua unidade inicial e diretório de trabalho.)

[in] lpStartupInfo

Um ponteiro para uma estrutura de STARTUPINFO ou STARTUPINFOEX.

Para definir atributos estendidos, use uma estrutura de STARTUPINFOEX e especifique EXTENDED_STARTUPINFO_PRESENT no parâmetro dwCreationFlags.

Os identificadores em STARTUPINFO ou STARTUPINFOEX devem ser fechados com CloseHandle quando não forem mais necessários.

Importante

O chamador é responsável por garantir que os campos de identificador padrão em STARTUPINFO contenham valores válidos de identificador. Esses campos são copiados inalterados para o processo filho sem validação, mesmo quando o membro dwFlags especifica STARTF_USESTDHANDLES. Valores incorretos podem fazer com que o processo filho se comporte mal ou falhe. Use a ferramenta de verificação Application Verifier runtime para detectar identificadores inválidos.

[out] lpProcessInformation

Um ponteiro para uma estrutura de PROCESS_INFORMATION que recebe informações de identificação sobre o novo processo.

Os identificadores no PROCESS_INFORMATION devem ser fechados com CloseHandle quando não forem mais necessários.

Valor de retorno

Se a função for bem-sucedida, o valor retornado não será zero.

Se a função falhar, o valor retornado será zero. Para obter informações de erro estendidas, chame GetLastError.

Observe que a função retorna antes que o processo termine a inicialização. Se uma DLL necessária não puder ser localizada ou falhar ao inicializar, o processo será encerrado. Para obter o status de encerramento de um processo, chame GetExitCodeProcess.

Observações

O processo recebe um identificador de processo. O identificador é válido até que o processo seja encerrado. Ele pode ser usado para identificar o processo ou especificado na função OpenProcess para abrir um identificador para o processo. O thread inicial no processo também recebe um identificador de thread. Ele pode ser especificado na função OpenThread para abrir um identificador para o thread. O identificador é válido até que o thread seja encerrado e possa ser usado para identificar exclusivamente o thread dentro do sistema. Esses identificadores são retornados na estrutura PROCESS_INFORMATION.

O nome do executável na linha de comando que o sistema operacional fornece a um processo não é necessariamente idêntico ao da linha de comando que o processo de chamada fornece à função CreateProcess. O sistema operacional pode preparar um caminho totalmente qualificado para um nome executável fornecido sem um caminho totalmente qualificado.

O thread de chamada pode usar a função WaitForInputIdle para aguardar até que o novo processo tenha terminado sua inicialização e esteja aguardando a entrada do usuário sem nenhuma entrada pendente. Isso pode ser útil para sincronização entre processos pai e filho, pois CreateProcess retorna sem esperar que o novo processo conclua sua inicialização. Por exemplo, o processo de criação usaria WaitForInputIdle antes de tentar encontrar uma janela associada ao novo processo.

A maneira preferida de desligar um processo é usando a função ExitProcess, pois essa função envia uma notificação de encerramento de aproximação para todas as DLLs anexadas ao processo. Outros meios de desligar um processo não notificam as DLLs anexadas. Observe que quando um thread chama ExitProcess, outros threads do processo são encerrados sem a oportunidade de executar qualquer código adicional (incluindo o código de terminação de thread de DLLs anexadas). Para obter mais informações, consulte Encerrando um processo.

Um processo pai pode alterar diretamente as variáveis de ambiente de um processo filho durante a criação do processo. Essa é a única situação em que um processo pode alterar diretamente as configurações de ambiente de outro processo. Para obter mais informações, consulte Alterando variáveis de ambiente.

Se um aplicativo fornecer um bloco de ambiente, as informações de diretório atuais das unidades do sistema não serão propagadas automaticamente para o novo processo. Por exemplo, há uma variável de ambiente chamada =C: cujo valor é o diretório atual na unidade C. Um aplicativo deve passar manualmente as informações do diretório atual para o novo processo. Para fazer isso, o aplicativo deve criar explicitamente essas cadeias de caracteres de variável de ambiente, classificá-las em ordem alfabética (porque o sistema usa um ambiente classificado) e colocá-las no bloco de ambiente. Normalmente, eles vão para a frente do bloco de ambiente, devido à ordem de classificação do bloco de ambiente.

Uma maneira de obter as informações atuais do diretório para uma unidade X é fazer a seguinte chamada: GetFullPathName("X:", ...). Isso evita que um aplicativo precise examinar o bloco de ambiente. Se o caminho completo retornado for X:, não será necessário passar esse valor como dados de ambiente, pois o diretório raiz é o diretório atual padrão para a unidade X de um novo processo.

Quando um processo é criado com CREATE_NEW_PROCESS_GROUP especificado, uma chamada implícita para SetConsoleCtrlHandler (NULL,TRUE) é feita em nome do novo processo; isso significa que o novo processo tem CTRL+C desabilitado. Isso permite que os shells lidem com CTRL+C e passem esse sinal seletivamente para sub-processos. CTRL+BREAK não está desabilitado e pode ser usado para interromper o grupo processo/processo.

Por padrão, passar verdadeiro como o valor do parâmetro bInheritHandles faz com que todas as alças herdáveis sejam herdadas pelo novo processo. Isso pode ser problemático para aplicativos que criam processos de vários threads simultaneamente, mas desejam que cada processo herde identificadores diferentes.

Os aplicativos podem usar a função UpdateProcThreadAttributeList com o parâmetro PROC_THREAD_ATTRIBUTE_HANDLE_LIST para fornecer uma lista de identificadores a serem herdados por um processo específico.

Comentários de segurança

O primeiro parâmetro, lpApplicationName, pode ser NULL, nesse caso, o nome executável deve estar na cadeia de caracteres delimitada por espaço em branco apontada por lpCommandLine. Se o nome executável ou caminho tiver um espaço nele, há o risco de que um executável diferente possa ser executado devido à maneira como a função analisa espaços. O exemplo a seguir é perigoso porque a função tentará executar "Program.exe", se existir, em vez de "MyApp.exe".

    LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
    CreateProcess(NULL, szCmdline, /* ... */);

Se um usuário mal-intencionado criar um aplicativo chamado "Program.exe" em um sistema, qualquer programa que chame incorretamente CreateProcess usando o diretório Arquivos de Programas executará esse aplicativo em vez do aplicativo pretendido.

Para evitar esse problema, não passe NULL para lpApplicationName. Se você passar NULL para lpApplicationName, use aspas ao redor do caminho executável em lpCommandLine, conforme mostrado no exemplo abaixo.

    LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\" -L -S"));
    CreateProcess(NULL, szCmdline, /*...*/);

Exemplos

Para obter um exemplo, consulte Criando processos.

Nota

O cabeçalho processthreadsapi.h define CreateProcess como um alias que seleciona automaticamente a versão ANSI ou Unicode dessa função com base na definição da constante do pré-processador UNICODE. A combinação do uso do alias neutro de codificação com código que não é neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Conventions for Function Prototypes.

Requisitos

Requisito Valor
de cliente com suporte mínimo Windows XP [aplicativos da área de trabalho | Aplicativos UWP]
servidor com suporte mínimo Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP]
da Plataforma de Destino Windows
cabeçalho processthreadsapi.h (inclua Windows.h no Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2)
biblioteca Kernel32.lib
de DLL Kernel32.dll

Consulte também

CloseHandle

ShellExecuteA

CreateProcessAsUser

CreateProcessWithLogonW

exitprocess

GetCommandLine

GetEnvironmentStrings

GetExitCodeProcess

GetFullPathName

GetStartupInfo

openprocess

PROCESS_INFORMATION

Funções de processo e thread

processos

SECURITY_ATTRIBUTES

STARTUPINFO

STARTUPINFOEX

SetErrorMode

TerminateProcess

WaitForInputIdle