crearproceso
La función CreateProcess de WIN32API se utiliza para crear un nuevo proceso y su hilo principal. Este nuevo proceso ejecuta el archivo ejecutable especificado.
Prototipo de función:
BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes.
LPSECURITY_ATTRIBUTES lpThreadAttributes.
BOOL bInheritHandles.
DWORD dwCreationFlags.
LPVOID lpEnvironment. >
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
Parámetros:
>lpApplicationName: apunta a una cadena terminada en NULL utilizada para especificar el módulo ejecutable.
Esta cadena puede ser una ruta absoluta al módulo ejecutable o una ruta relativa. En el último caso, la función utiliza la unidad y el directorio actuales para establecer la ruta al módulo ejecutable.
Este parámetro se puede establecer en NULL, en cuyo caso el nombre del módulo ejecutable debe estar al principio del parámetro lpCommandLine y separado de los siguientes caracteres por un carácter de espacio.
El módulo especificado puede ser una aplicación Win32. También pueden ser otros tipos de módulos (como MS-DOS u OS/2) si el subsistema apropiado está disponible en la computadora actual.
En Windows NT, si el módulo ejecutable es una aplicación de 16 bits, entonces este parámetro debe establecerse en NULL y el nombre del módulo ejecutable debe especificarse en el parámetro lpCommandLine. Las aplicaciones de 16 bits se ejecutan como procesos utilizando una máquina virtual DOS o Windows en Win32 (WOW).
lpCommandLine: apunta a una línea de comando terminada en NULL que se utiliza para especificar la línea de comando que se ejecutará.
Este parámetro puede estar vacío, entonces la función utilizará la cadena especificada por el parámetro como línea de comando del programa a ejecutar.
Si los parámetros lpApplicationName y lpCommandLine están vacíos, entonces el parámetro lpApplicationName especifica el módulo que se ejecutará y el parámetro lpCommandLine especifica la línea de comando del módulo que se ejecutará. Un proceso recién ejecutado puede obtener la línea de comando completa usando la función GetCommandLine. Los programas en lenguaje C pueden utilizar parámetros argc y argv.
Si el parámetro lpApplicationName está vacío, entonces el primer elemento separado por espacios en esta cadena especifica el nombre del módulo ejecutable. Si el nombre del archivo no contiene una extensión, se asumirá que .exe es la extensión predeterminada.
Si el nombre del archivo termina con un punto (.) y no tiene extensión, o el nombre del archivo contiene una ruta, no se agregará .exe. Si el nombre del archivo no contiene una ruta, Windows buscará el archivo ejecutable en el siguiente orden:
1. El directorio de la aplicación actual.
2. Directorio del proceso padre.
3. Windows 95: Directorio del sistema de Windows, que se puede obtener mediante la función GetSystemDirectory.
Windows NT: directorio del sistema Windows de 32 bits. Se puede obtener utilizando la función GetSystemDirectory. El nombre del directorio es SYSTEM32.
4. En Windows NT: directorio del sistema Windows de 16 bits. Este directorio no se puede obtener usando las funciones de Win32, pero se buscará y el nombre del directorio es SISTEMA.
5. Directorio de Windows. Este directorio se puede obtener utilizando la función GetWindowsDirectory.
6. Directorios listados en la variable de entorno PATH.
Si el proceso que se está creando es una aplicación basada en MS-DOS o Windows de 16 bits, el parámetro lpCommandLine debe ser una ruta absoluta con el nombre del archivo ejecutable como primer elemento, porque Al hacer esto hará que los programas de Windows de 32 bits funcionen bien y configurar el parámetro lpCommandLine de esta manera es la forma más sólida.
lpProcessAttributes: apunta a una estructura SECURITY_ATTRIBUTES, que determina si el proceso hijo puede heredar el identificador devuelto. Si el parámetro lpProcessAttributes es NULL, el identificador no se puede heredar.
En Windows NT: el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES especifica el descriptor de seguridad del nuevo proceso. Si el parámetro está vacío, el nuevo proceso utiliza el descriptor de seguridad predeterminado.
En Windows95: se ignora el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES.
lpThreadAttributes: apunta a una estructura SECURITY_ATTRIBUTES, que determina si el proceso hijo puede heredar el identificador devuelto. Si el parámetro lpThreadAttributes es NULL, el identificador no se puede heredar.
En Windows NT, el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES especifica el descriptor de seguridad del hilo principal. Si el parámetro está vacío, el hilo principal usa el descriptor de seguridad predeterminado.
En Windows95: se ignora el miembro lpSecurityDescriptor de la estructura SECURITY_ATTRIBUTES.
bInheritHandles: Indica si el nuevo proceso heredó los identificadores del proceso que llama. Si el valor del parámetro es verdadero, cada identificador abierto heredable en el proceso de llamada será heredado por el proceso hijo. El identificador heredado tiene exactamente el mismo valor y derechos de acceso que el proceso original.
dwCreationFlags: Especifica indicadores adicionales utilizados para controlar la creación de clases y procesos de prioridad. Los siguientes indicadores de creación se pueden especificar en cualquier combinación excepto los que se enumeran a continuación.
Valor: CREATE_DEFAULT_ERROR_MODE
Significado: El nuevo proceso no hereda el modo de error del proceso que llama.
La función CreateProcess asigna al nuevo proceso el modo de error predeterminado actual como alternativa. Las aplicaciones pueden llamar a la función SetErrorMode para establecer el modo de error predeterminado actual.
Este indicador es útil para shells multiproceso que se ejecutan en un entorno sin errores de hardware.
Para la función CreateProcess, el comportamiento predeterminado es que el nuevo proceso herede el modo de error de la persona que llama. Establezca esta bandera para cambiar el manejo predeterminado.
Valor: CREATE_NEW_CONSOLE
Significado: El nuevo proceso utilizará una nueva consola en lugar de heredar la consola del proceso padre. Este indicador no se puede utilizar con el indicador DETACHED_PROCESS.
Valor: CREATE_NEW_PROCESS_GROUP
Significado: El nuevo proceso será el proceso raíz de un árbol de procesos. Todos los procesos en el árbol de procesos son procesos secundarios del proceso raíz. El identificador de usuario del nuevo árbol de procesos es el mismo que el identificador de este proceso, devuelto por el parámetro lpProcessInformation. Los árboles de procesos suelen utilizar la función GenerateConsoleCtrlEvent para permitir el envío de señales CTRL C o CTRL BREAK a un grupo de procesos de consola.
Valor: CREATE_SEPARATE_WOW_VDM
Significado: (sólo Windows NT) Este indicador sólo es válido cuando se ejecuta una aplicación de Windows de 16 bits. Si se configura, el nuevo proceso se ejecutará en una máquina DOS virtual privada (VDM). Además, de forma predeterminada, todas las aplicaciones de Windows de 16 bits se ejecutarán en subprocesos en el mismo VDM compartido. La ventaja de ejecutar un programa de 16 bits solo es que la falla de una aplicación solo finalizará el funcionamiento de este VDM; otros programas que se ejecutan en diferentes VDM continuarán ejecutándose normalmente; Del mismo modo, las aplicaciones de Windows de 16 bits que se ejecutan en diferentes VDM tienen diferentes colas de entrada, lo que significa que si una aplicación deja de responder temporalmente, las aplicaciones en VDM separados pueden continuar recibiendo entradas.
Valor: CREATE_SHARED_WOW_VDM
Significado: (solo Windows NT) Este indicador solo es válido cuando se ejecuta una aplicación de Windows de 16 bits. Si la opción DefaultSeparateVDM en la sección Windows de WIN.INI está configurada en verdadero, este indicador hace que la función CreateProcess anule esta opción y ejecute el nuevo proceso en la máquina DOS virtual compartida.
Valor: CREATE_SUSPENDED
Significado: El hilo principal del nuevo proceso se creará en un estado suspendido y no se ejecutará hasta que se llame a la función ResumeThread.
Valor: CREATE_UNICODE_ENVIRONMENT
Significado: Si está configurado, el bloque de entorno especificado por el parámetro lpEnvironment usa caracteres Unicode. Si está vacío, el bloque de entorno usa caracteres ANSI.
Valor: DEBUG_PROCESS
Significado: Si se establece este indicador, el proceso que llama se tratará como un depurador y el nuevo proceso se tratará como el proceso depurado. El sistema notifica al depurador de todos los eventos de depuración que ocurren en el programa depurado.
Si usa este indicador para crear un proceso, solo el proceso que llama (el proceso que llama a la función CreateProcess) puede llamar a la función WaitForDebugEvent.
Valor: DEBUG_ONLY_THIS_PROCESS
Significado: Si este indicador no está configurado y el proceso de llamada se está depurando, el nuevo proceso se convertirá en otro objeto de depuración del depurador que depuró el proceso de llamada.
Si el proceso de llamada no se depura, no se producirá ningún comportamiento relacionado con la depuración.
Valor: DETACHED_PROCESS
Significado: Para procesos de consola, el nuevo proceso no tiene acceso a la consola del proceso padre. Los nuevos procesos pueden crear ellos mismos una nueva consola a través de la función AllocConsole. Esta bandera no se puede utilizar con la bandera CREATE_NEW_CONSOLE.
El parámetro dwCreationFlags también se usa para controlar la clase de prioridad del nuevo proceso. La clase de prioridad se usa para determinar la prioridad de programación de subprocesos de este proceso. Si no se especifica ninguno de los siguientes indicadores de clase de prioridad, la clase de prioridad predeterminada es NORMAL_PRIORITY_CLASS, a menos que el proceso que se está creando sea IDLE_PRIORITY_CLASS. En este caso, la clase de prioridad predeterminada del proceso hijo es IDLE_PRIORITY_CLASS.
Puede ser uno de los siguientes indicadores:
Prioridad: HIGH_PRIORITY_CLASS
Significado: Indica que este proceso realizará una tarea de tiempo crítico, por lo que debe ser comenzó inmediatamente Ejecute para garantizar la corrección. Los programas en este nivel de prioridad tienen prioridad sobre los programas de prioridad normal o inactivos. Un ejemplo es la lista de tareas de Windows, que deja de considerar la carga del sistema para garantizar que pueda responder inmediatamente cuando el usuario lo llama. Asegúrese de utilizar la prioridad alta con precaución, ya que una aplicación vinculada a la CPU de alta prioridad puede consumir casi todo el tiempo disponible de la CPU.
Prioridad: IDLE_PRIORITY_CLASS
Significado: Indica que el hilo de este proceso solo se ejecutará cuando el sistema esté inactivo y puede ser interrumpido por cualquier tarea de alta prioridad. Como salvapantallas. La prioridad inactiva la heredan los procesos secundarios.
Prioridad: NORMAL_PRIORITY_CLASS
Significado: Indica que este proceso no tiene requisitos especiales de programación de tareas.
Prioridad: REALTIME_PRIORITY_CLASS
Significado: Indica que este proceso tiene la mayor prioridad disponible. Un subproceso de un proceso con prioridad en tiempo real puede interrumpir la ejecución de todos los demás subprocesos del proceso, incluidos los procesos del sistema que realizan tareas importantes. Por ejemplo, un proceso en tiempo real que tarda un poco más en ejecutarse puede provocar una caché de disco insuficiente o una respuesta lenta del mouse.
lpEnvironment: Apunta al bloque de entorno de un nuevo proceso. Si este parámetro está vacío, el nuevo proceso utiliza el entorno del proceso que llama.
Existe un bloque de entorno dentro de un bloque de cadenas terminadas en NULL, que también está terminada en NULL. Cada cadena tiene el formato nombre=valor.
Dado que el indicador de igualdad se trata como un delimitador, una variable de entorno no puede utilizarlo como nombre de variable.
En lugar de utilizar el bloque de entorno proporcionado por la aplicación, es mejor configurar este parámetro en vacío. La información del directorio actual en la unidad del sistema no se pasará automáticamente al proceso recién creado. Para obtener información sobre esta situación y cómo abordarla, consulte la sección Notas.
Los bloques de entorno pueden contener caracteres Unicode o ANSI. Si el bloque de entorno al que apunta lpEnvironment contiene caracteres Unicode, se establecerá el indicador CREATE_UNICODE_ENVIRONMENT del campo dwCreationFlags. Si el bloque contiene caracteres ANSI, este indicador se borrará.
Tenga en cuenta que un bloque de entorno ANSI finaliza con dos bytes cero: uno es el final de la cadena y el otro se utiliza para terminar el bloque. Un bloque de entorno Unicode termina con cuatro bytes cero: dos representan el final de la cadena y los otros dos se utilizan para terminar el bloque.
lpCurrentDirectory: apunta a una cadena terminada en NULL. Esta cadena se utiliza para especificar la ruta de trabajo del proceso secundario. Esta cadena debe ser una ruta absoluta que contenga el nombre de la unidad. Si este parámetro está vacío, el nuevo proceso utilizará la misma unidad y directorio que el proceso de llamada. Esta opción es un requisito principal para un shell que inicia aplicaciones de inicio y especifica sus unidades y directorios de trabajo.
lpStartupInfo: Apunta a una estructura STARTUPINFO utilizada para determinar cómo se muestra el formulario principal del nuevo proceso.
lpProcessInformation: Apunta a una estructura PROCESS_INFORMATION utilizada para recibir la información de identificación del nuevo proceso.
Valor de retorno:
Si la función se ejecuta correctamente, se devuelve un valor distinto de cero.
Si la función no se ejecuta y devuelve cero, puedes utilizar la función GetLastError para obtener información adicional sobre el error.
Nota:
La función CreateProcess se utiliza para ejecutar un nuevo programa. Las funciones WinExec y LoadModule todavía están disponibles, pero también se implementan llamando a la función CreateProcess.
Además, la función CreateProcess no solo crea un proceso, sino que también crea un objeto de hilo. Este hilo se creará junto con una pila inicializada; el tamaño de la pila está determinado por la descripción en el encabezado del archivo ejecutable. La ejecución del hilo comienza desde el encabezado del archivo.
Se crean identificadores de nuevos procesos y nuevos hilos con acceso global. Si no hay un descriptor de seguridad para ninguno de los identificadores, entonces el identificador se puede utilizar en cualquier función que requiera el tipo de identificador como parámetro. Cuando se proporciona un descriptor de seguridad, cuando se utiliza posteriormente el identificador, siempre se realiza primero una verificación del permiso de acceso. Si la verificación del permiso de acceso deniega el acceso, el proceso solicitante no podrá utilizar este identificador para acceder al proceso.
A este proceso se le asignará un identificador de proceso de 32 bits. Este identificador es válido hasta que finalice el proceso. Puede usarse para identificar el proceso o especificarse en la función OpenProcess para abrir un identificador del proceso. A los subprocesos inicializados en el proceso también se les asignará un identificador de subproceso de 32 bits. Este identificador es válido hasta que finalice el condado y puede usarse para identificar de forma única este hilo en el sistema. Estos identificadores se devuelven en la estructura PROCESS_INFORMATION.
Cuando se especifica el nombre de una aplicación en el parámetro lpApplicationName o lpCommandLine, si el nombre de la aplicación contiene una extensión no afectará la operación, con la excepción de un caso: un MS con una extensión .com. Los programas o programas de Windows deben contener la extensión .com.
El proceso que llama puede esperar a que el nuevo proceso complete su inicialización y esperar la entrada del usuario a través de la función WaitForInputIdle. Esto es extremadamente útil para la sincronización entre procesos padre e hijo, porque la función CreateProcess no espera a que el nuevo proceso complete su trabajo de inicialización. Por ejemplo, un proceso debería llamar a WaitForInputIdle antes de intentar asociar una ventana con un nuevo proceso.
La forma preferida de finalizar un proceso es llamar a la función ExitProcess, porque esta función notifica a todas las bibliotecas de vínculos dinámicos (DLL) del proceso que el programa ha entrado en el estado de terminación. Otros métodos para finalizar un proceso no notifican a la biblioteca de vínculos dinámicos asociada. Tenga en cuenta que cuando un proceso llama a ExitProcess, otros condados en el proceso no tienen la oportunidad de ejecutar ningún otro código (incluido el código de terminación de la biblioteca de vínculos dinámicos asociada).
ExitProcess, ExitThread, CreateThread, CreateRemoteThread, cuando se inicia un proceso (el resultado de llamar a CreateProcess) se serializa en el proceso. Dentro de un espacio de direcciones, sólo uno de estos eventos puede ocurrir al mismo tiempo. Esto significa que se mantendrán las siguientes restricciones:
* Durante las fases de inicio del proceso e inicialización de DLL, se pueden crear nuevos subprocesos, pero no pueden comenzar a ejecutarse hasta que se complete la inicialización de DLL del proceso.
*Solo puede haber un hilo en el proceso durante la inicialización de la DLL o la rutina de descarga.
*La función ExitProcess no regresa hasta que todos los subprocesos hayan completado la inicialización o descarga de la DLL.
Un proceso permanecerá en el sistema hasta que todos los subprocesos del proceso hayan finalizado y todos los identificadores del proceso y sus subprocesos hayan finalizado llamando a la función CloseHandle. Tanto el proceso como los identificadores del hilo principal deben cerrarse llamando a la función CloseHandle. Si estos identificadores ya no son necesarios, es mejor cerrarlos inmediatamente después de crear el proceso.
Cuando finaliza el último hilo del proceso, ocurren los siguientes eventos:
*Todos los objetos abiertos por el proceso se cerrarán.
*El estado de finalización del proceso (devuelto por la función GetExitCodeProcess) cambia desde su valor inicial STILL_ACTIVE al estado final del último hilo terminado.
*El objeto de subproceso del subproceso principal se establece en el estado de bandera para que lo utilicen otros subprocesos que esperan este objeto.
*El objeto de proceso se establece en el estado de bandera para que lo utilicen otros subprocesos que esperan este objeto.
Supongamos que el directorio actual en la unidad C es \MSVC\MFC y hay una variable de entorno llamada C:, y su valor es C:\MSVC\MFC, como se mencionó anteriormente en lpEnvironment. La información del directorio en dicha unidad del sistema no se pasará automáticamente al nuevo proceso cuando el parámetro lpEnvironment de la función CreateProcess no esté vacío. Una aplicación debe pasar manualmente la información del directorio actual al nuevo proceso. Para hacer esto, la aplicación debe crear directamente las cadenas de entorno, ordenarlas alfabéticamente (porque Windows NT y Windows 95 usan una variable de entorno simplificada) y colocarlas en el bloque de entorno especificado en lpEnvironment. De manera similar, deben encontrar el comienzo del bloque ambiental y repetir el orden de los bloques ambientales mencionado anteriormente.
Una forma de obtener la variable de directorio actual para la unidad X es llamar a GetFullPathName("x:", ..). Esto evita que una aplicación tenga que escanear bloques del entorno. Si la ruta absoluta devuelta es X:\, no es necesario pasar este valor como datos del entorno, porque el directorio raíz es el directorio actual predeterminado para nuevos procesos en la unidad X.
El identificador devuelto por la función CreateProcess tiene derechos de acceso PROCESS_ALL_ACCESS al objeto de proceso.
El directorio actual del objeto de proceso hijo especificado por el parámetro lpcurrentDirectory. El segundo elemento especificado por el parámetro lpCommandLine es el directorio actual del proceso principal.
Para Windows NT, cuando se crea un proceso con CREATE_NEW_PROCESS_GROUP especificado, se utiliza una llamada a SetConsoleCtrlHandler(NULL, True) en el nuevo proceso, lo que significa que el nuevo proceso dice CTRL C no es válido. Esto permite que el programa quirúrgico de nivel superior maneje los mensajes CTRL C por sí mismo y pase selectivamente estas señales a los procesos secundarios.
CTRL BREAK sigue siendo válido y se puede utilizar para interrumpir la ejecución de un proceso/árbol de procesos.
Ver
AllocConsole, CloseHandle, CreateRemoteThread, CreateThread, ExitProcess, ExitThread, GenerateConsoleCtrlEvent, GetCommandLine, GetEnvironmentStrings, GetExitCodeProcess, GetFullPathName, GetStartupInfo, GetSystemDirectory, GetWindowsDirectory, LoadModule, OpenProcess, PROCESS_INFORMATION, umeThread , SECURITY_ATTRIBUTES, SetConsoleCtrlHandler, SetErrorMode, STARTUPINFO, TerminateProcess, WaitForInputIdle, WaitForDebugEvent, WinExec