CreateProcessA-Funktion (processthreadsapi.h)

Erstellt einen neuen Prozess und seinen primären Thread. Der neue Prozess wird im Sicherheitskontext des Aufrufvorgangs ausgeführt.

Wenn der Aufrufvorgang einen anderen Benutzer imitiert, verwendet der neue Prozess das Token für den Aufrufvorgang, nicht das Identitätstoken. Um den neuen Prozess im Sicherheitskontext des Benutzers auszuführen, der durch das Identitätstoken dargestellt wird, verwenden Sie die Funktion CreateProcessAsUser oder CreateProcessWithLogonW .

Syntax

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
);

Parameter

[in, optional] lpApplicationName

Der Name des zu ausführenden Moduls. Dieses Modul kann eine Windows-basierte Anwendung sein. Es kann ein anderes Modultyp (z. B. MS-DOS oder OS/2) sein, wenn das entsprechende Subsystem auf dem lokalen Computer verfügbar ist.

Die Zeichenfolge kann den vollständigen Pfad und dateinamen des Moduls angeben, das ausgeführt werden soll, oder es kann einen Teilnamen angeben. Bei einem Teilnamen verwendet die Funktion das aktuelle Laufwerk und das aktuelle Verzeichnis, um die Spezifikation abzuschließen. Die Funktion verwendet den Suchpfad nicht. Dieser Parameter muss die Dateinamenerweiterung enthalten; Es wird keine Standarderweiterung angenommen.

Der lpApplicationName-Parameter kann NULL sein. In diesem Fall muss der Modulname das erste leerzeichendelimitierte Token in der lpCommandLine-Zeichenfolge sein. Wenn Sie einen langen Dateinamen verwenden, der einen Leerzeichen enthält, verwenden Sie zitate Zeichenfolgen, um anzugeben, wo der Dateinamen endet und die Argumente beginnen; andernfalls ist der Dateinamen mehrdeutig. Betrachten Sie beispielsweise die Zeichenfolge "c:\program files\sub dir\program name". Diese Zeichenfolge kann auf mehrere Arten interpretiert werden. Das System versucht, die Möglichkeiten in der folgenden Reihenfolge zu interpretieren:

  1. c:\program.exe
  2. c:\programm files\sub.exe
  3. c:\Programmdateien\unter dir\program.exe
  4. c:\Programmdateien\Unter dir\Programm name.exe

Wenn das ausführbare Modul eine 16-Bit-Anwendung ist, sollte lpApplicationNameNULL sein, und die Zeichenfolge, die auf lpCommandLine verweist, sollte das ausführbare Modul sowie seine Argumente angeben.

Um eine Batchdatei auszuführen, müssen Sie den Befehlsinterpreter starten; legen Sie lpApplicationName auf cmd.exe fest und legen Sie lpCommandLine auf die folgenden Argumente fest: /c plus den Namen der Batchdatei.

[in, out, optional] lpCommandLine

Die zu ausführende Befehlszeile.

Die maximale Länge dieser Zeichenfolge beträgt 32.767 Zeichen, einschließlich des Unicode-Endzeichens null. Wenn lpApplicationNameNULL ist, ist der Modulnameteil von lpCommandLine auf MAX_PATH Zeichen beschränkt.

Die Unicode-Version dieser Funktion, CreateProcessW, kann den Inhalt dieser Zeichenfolge ändern. Daher kann dieser Parameter kein Zeiger für schreibgeschützten Arbeitsspeicher sein (z. B. eine Konstvariable oder eine Literalzeichenfolge). Wenn dieser Parameter eine konstante Zeichenfolge ist, kann die Funktion zu einer Zugriffsverletzung führen.

Der lpCommandLine-Parameter kann NULL sein. In diesem Fall verwendet die Funktion die Zeichenfolge, die von lpApplicationName als Befehlszeile verweist.

Wenn sowohl lpApplicationName als auch lpCommandLine nicht NULL sind, gibt die null-beendete Zeichenfolge, die von lpApplicationName darauf verweist, das Modul an, das ausgeführt werden soll, und die null-beendete Zeichenfolge, die von lpCommandLine angibt, die Befehlszeile angibt. Der neue Prozess kann GetCommandLine verwenden, um die gesamte Befehlszeile abzurufen. Konsolenprozesse, die in C geschrieben wurden, können die Argc - und Argv-Argumente verwenden, um die Befehlszeile zu analysieren. Da argv[0] der Modulname ist, wiederholen C-Programmierer im Allgemeinen den Modulnamen als erstes Token in der Befehlszeile.

Wenn lpApplicationName NULL ist, gibt das erste leerzeichendelimitierte Token der Befehlszeile den Modulnamen an. Wenn Sie einen langen Dateinamen verwenden, der einen Leerraum enthält, verwenden Sie zitate Zeichenfolgen, um anzugeben, wo der Dateinamen endet und die Argumente beginnen (siehe die Erklärung für den lpApplicationName-Parameter ). Wenn der Dateinamen keine Erweiterung enthält, wird .exe angefügt. Wenn also die Dateinamenerweiterung .com ist, muss dieser Parameter die Erweiterung .com enthalten. Wenn der Dateinamen in einem Zeitraum (.) ohne Erweiterung endet oder wenn der Dateinamen einen Pfad enthält, wird .exe nicht angefügt. Wenn der Dateinamen keinen Verzeichnispfad enthält, sucht das System nach der ausführbaren Datei in der folgenden Sequenz:

  1. Das Verzeichnis, aus dem die Anwendung geladen wurde.
  2. Das aktuelle Verzeichnis für den übergeordneten Prozess.
  3. Das 32-Bit-Windows-Systemverzeichnis. Verwenden Sie die GetSystemDirectory-Funktion , um den Pfad dieses Verzeichnisses abzurufen.
  4. Das 16-Bit-Windows-Systemverzeichnis. Es gibt keine Funktion, die den Pfad dieses Verzeichnisses abruft, aber es wird durchsucht. Der Name dieses Verzeichnisses ist System.
  5. Das Windows-Verzeichnis. Verwenden Sie die GetWindowsDirectory-Funktion , um den Pfad dieses Verzeichnisses abzurufen.
  6. Die Verzeichnisse, die in der PATH-Umgebungsvariable aufgeführt sind. Beachten Sie, dass diese Funktion den vom Registrierungsschlüssel für App-Pfade angegebenen Anwendungspfad nicht durchsucht. Um diesen Anwendungspfad in die Suchsequenz einzuschließen, verwenden Sie die ShellExecute-Funktion .
Das System fügt dem Befehlszeilenzeichenfolgenzeichen ein terminierendes Nullzeichen hinzu, um den Dateinamen von den Argumenten zu trennen. Dadurch wird die ursprüngliche Zeichenfolge in zwei Zeichenfolgen für die interne Verarbeitung unterteilt.

[in, optional] lpProcessAttributes

Ein Zeiger auf eine SECURITY_ATTRIBUTES Struktur, die bestimmt, ob der zurückgegebene Handle an das neue Prozessobjekt von untergeordneten Prozessen geerbt werden kann. Wenn lpProcessAttributesNULL ist, kann der Handle nicht geerbt werden.

Das LpSecurityDescriptor-Element der Struktur gibt einen Sicherheitsdeskriptor für den neuen Prozess an. Wenn lpProcessAttributes NULL ist oder lpSecurityDescriptorNULL ist, ruft der Prozess einen Standardsicherheitsdeskriptor ab. Die ACLs im Standardsicherheitsdeskriptor für einen Prozess stammen aus dem primären Token des Creators. Windows XP: Die ACLs im Standardsicherheitsdeskriptor für einen Prozess stammen aus dem primären oder Identitätstoken des Erstellers. Dieses Verhalten wurde mit Windows XP mit SP2 und Windows Server 2003 geändert.

[in, optional] lpThreadAttributes

Ein Zeiger auf eine SECURITY_ATTRIBUTES Struktur, die bestimmt, ob der zurückgegebene Handle an das neue Threadobjekt von untergeordneten Prozessen geerbt werden kann. Wenn lpThreadAttributes NULL ist, kann der Handle nicht geerbt werden.

Das LpSecurityDescriptor-Element der Struktur gibt einen Sicherheitsdeskriptor für den Hauptthread an. Wenn lpThreadAttributes NULL ist oder lpSecurityDescriptor NULL ist, ruft der Thread einen Standardsicherheitsdeskriptor ab. Die ACLs im Standardsicherheitsdeskriptor für einen Thread stammen aus dem Prozesstoken. Windows XP: Die ACLs im Standardsicherheitsdeskriptor für einen Thread stammen aus dem primären oder Identitätstoken des Creators. Dieses Verhalten wurde mit Windows XP mit SP2 und Windows Server 2003 geändert.

[in] bInheritHandles

Wenn dieser Parameter WAHR ist, wird jedes vererbbare Handle im Aufrufprozess durch den neuen Prozess geerbt. Wenn der Parameter FALSE ist, werden die Handle nicht geerbt. Beachten Sie, dass geerbte Handle den gleichen Wert und Zugriffsrechte wie die ursprünglichen Handle haben. Weitere Diskussionen über vererbbare Handle finden Sie unter Hinweise.

Terminaldienste: Sie können keine Handle über Sitzungen erben. Wenn dieser Parameter "TRUE" ist, müssen Sie den Prozess in derselben Sitzung wie der Aufrufer erstellen.

Geschützte Prozesslicht(PPL)-Prozesse: Die generische Vererbung des Handles wird blockiert, wenn ein PPL-Prozess einen nicht-PPL-Prozess erstellt, da PROCESS_DUP_HANDLE nicht von einem PPL-Prozess an einen PPL-Prozess zulässig ist. Siehe Prozesssicherheits- und Zugriffsrechte

[in] dwCreationFlags

Die Flags, die die Prioritätsklasse und die Erstellung des Prozesses steuern. Eine Liste der Werte finden Sie unter "Prozesserstellungs-Flags".

Dieser Parameter steuert auch die Prioritätsklasse des neuen Prozesses, die verwendet wird, um die Planungsprioritäten der Threads des Prozesses zu bestimmen. Eine Liste der Werte finden Sie unter GetPriorityClass. Wenn keine der Prioritätsklassen-Flags angegeben ist, wird die Prioritätsklasse standardmäßig NORMAL_PRIORITY_CLASS , sofern die Prioritätsklasse des Erstellungsprozesses IDLE_PRIORITY_CLASS oder BELOW_NORMAL_PRIORITY_CLASS ist. In diesem Fall erhält der untergeordnete Prozess die Standardprioritätsklasse des Aufrufvorgangs.

Wenn der DwCreationFlags-Parameter einen Wert von 0 aufweist:

  • Der Prozess erbt sowohl den Fehlermodus des Anrufers als auch die Konsole des übergeordneten Elements.
  • Der Umgebungsblock für den neuen Prozess wird angenommen, ANSI-Zeichen zu enthalten (siehe lpEnvironment-Parameter für zusätzliche Informationen).
  • Eine windowsbasierte 16-Bit-Anwendung wird auf einem freigegebenen virtuellen DOS-Computer (VDM) ausgeführt.

[in, optional] lpEnvironment

Ein Zeiger auf den Umgebungsblock für den neuen Prozess. Wenn dieser Parameter NULL ist, verwendet der neue Prozess die Umgebung des Aufrufvorgangs.

Ein Umgebungsblock besteht aus einem null-beendeten Block von null-beendeten Zeichenfolgen. Jede Zeichenfolge befindet sich in der folgenden Form:

Namen=Wert\0

Da das Gleichheitszeichen als Trennzeichen verwendet wird, darf es nicht im Namen einer Umgebungsvariable verwendet werden.

Ein Umgebungsblock kann entweder Unicode- oder ANSI-Zeichen enthalten. Wenn der Umgebungsblock von lpEnvironment Unicode-Zeichen enthält, achten Sie darauf, dass dwCreationFlagsCREATE_UNICODE_ENVIRONMENT enthält. Wenn dieser Parameter NULL ist und der Umgebungsblock des übergeordneten Prozesses Unicode-Zeichen enthält, müssen Sie auch sicherstellen, dass dwCreationFlagsCREATE_UNICODE_ENVIRONMENT enthält.

Die ANSI-Version dieser Funktion schlägt CreateProcessA fehl, wenn die Gesamtgröße des Umgebungsblocks für den Prozess 32.767 Zeichen überschreitet.

Beachten Sie, dass ein ANSI-Umgebungsblock mit zwei Nullbyte beendet wird: eine für die letzte Zeichenfolge, eine weitere, um den Block zu beenden. Ein Unicode-Umgebungsblock wird um vier Nullbyte beendet: zwei für die letzte Zeichenfolge, zwei weitere, um den Block zu beenden.

[in, optional] lpCurrentDirectory

Der vollständige Pfad zum aktuellen Verzeichnis für den Prozess. Die Zeichenfolge kann auch einen UNC-Pfad angeben.

Wenn dieser Parameter NULL ist, weist der neue Prozess das gleiche aktuelle Laufwerk und verzeichnis wie der aufrufende Prozess auf. (Dieses Feature wird hauptsächlich für Shells bereitgestellt, die eine Anwendung starten müssen, und geben Sie das ursprüngliche Laufwerk und das Arbeitsverzeichnis an.)

[in] lpStartupInfo

Ein Zeiger auf eine STARTUPINFO - oder STARTUPINFOEX-Struktur .

Verwenden Sie zum Festlegen erweiterter Attribute eine STARTUPINFOEX-Struktur , und geben Sie EXTENDED_STARTUPINFO_PRESENT im dwCreationFlags-Parameter an.

Handle in STARTUPINFO oder STARTUPINFOEX müssen mit CloseHandle geschlossen werden, wenn sie nicht mehr benötigt werden.

Wichtig Der Aufrufer ist dafür verantwortlich, sicherzustellen, dass die Standardhandpunktfelder in STARTUPINFO gültige Handlewerte enthalten. Diese Felder werden unverändert in den untergeordneten Prozess kopiert, auch wenn das dwFlags-Element STARTF_USESTDHANDLES angibt. Falsche Werte können dazu führen, dass der untergeordnete Prozess fehlbe rasiert oder abstürzt. Verwenden Sie das Überprüfungstool für die Anwendungsüberprüfung zur Laufzeit, um ungültige Handle zu erkennen.
 

[out] lpProcessInformation

Ein Zeiger auf eine PROCESS_INFORMATION Struktur, die Identifikationsinformationen zum neuen Prozess empfängt.

Ziehpunkte in PROCESS_INFORMATION müssen mit CloseHandle geschlossen werden, wenn sie nicht mehr benötigt werden.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert ungleich Null.

Wenn die Funktion fehlerhaft ist, ist der Rückgabewert null. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Beachten Sie, dass die Funktion zurückgibt, bevor der Prozess die Initialisierung abgeschlossen hat. Wenn sich eine erforderliche DLL nicht befindet oder nicht initialisiert werden kann, wird der Prozess beendet. Rufen Sie GetExitCodeProcess auf, um den Beendigungsstatus eines Prozesses abzurufen.

Hinweise

Der Prozess wird einem Prozessbezeichner zugewiesen. Der Bezeichner ist gültig, bis der Prozess beendet wird. Es kann verwendet werden, um den Prozess zu identifizieren oder in der OpenProcess-Funktion angegeben, um einen Handle für den Prozess zu öffnen. Der anfängliche Thread im Prozess wird auch einem Threadbezeichner zugewiesen. Es kann in der OpenThread-Funktion angegeben werden, um einen Handle für den Thread zu öffnen. Der Bezeichner ist gültig, bis der Thread beendet wird und verwendet werden kann, um den Thread innerhalb des Systems eindeutig zu identifizieren. Diese Bezeichner werden in der PROCESS_INFORMATION Struktur zurückgegeben.

Der Name der ausführbaren Datei in der Befehlszeile, die das Betriebssystem für einen Prozess bereitstellt, ist nicht unbedingt identisch mit der Befehlszeile, die der Aufrufenprozess der CreateProcess-Funktion zugibt. Das Betriebssystem kann einen vollqualifizierten Pfad zu einem ausführbaren Namen bereitstellen, der ohne vollqualifizierten Pfad bereitgestellt wird.

Der aufrufende Thread kann die WaitForInputIdle-Funktion verwenden, um zu warten, bis der neue Prozess seine Initialisierung abgeschlossen hat und auf die Benutzereingabe wartet, ohne dass die Eingabe aussteht. Dies kann für die Synchronisierung zwischen übergeordneten und untergeordneten Prozessen nützlich sein, da CreateProcess zurückgibt, ohne darauf zu warten, dass der neue Prozess die Initialisierung abgeschlossen hat. Der Erstellungsprozess würde beispielsweise WaitForInputIdle verwenden, bevor versucht wird, ein Fenster zu finden, das dem neuen Prozess zugeordnet ist.

Die bevorzugte Möglichkeit zum Herunterfahren eines Prozesses besteht darin, die ExitProcess-Funktion zu verwenden, da diese Funktion Benachrichtigungen über die Beendigung aller DLLs sendet, die an den Prozess angefügt sind. Andere Mittel zum Herunterfahren eines Prozesses benachrichtigen die angefügten DLLs nicht. Beachten Sie, dass, wenn ein Thread ExitProcess aufruft, andere Threads des Prozesses beendet werden, ohne dass zusätzlichen Code ausgeführt werden kann (einschließlich des Thread-Beendigungscodes von angefügten DLLs). Weitere Informationen finden Sie unter "Beenden eines Prozesses".

Ein übergeordneter Prozess kann die Umgebungsvariablen eines untergeordneten Prozesses während der Prozesserstellung direkt ändern. Dies ist die einzige Situation, wenn ein Prozess die Umgebungseinstellungen eines anderen Prozesses direkt ändern kann. Weitere Informationen finden Sie unter Ändern von Umgebungsvariablen.

Wenn eine Anwendung einen Umgebungsblock bereitstellt, werden die aktuellen Verzeichnisinformationen der Systemlaufwerke nicht automatisch an den neuen Prozess weitergegeben. Beispielsweise gibt es eine Umgebungsvariable mit dem Namen =C: dessen Wert das aktuelle Verzeichnis auf Laufwerk C ist. Eine Anwendung muss die aktuellen Verzeichnisinformationen manuell an den neuen Prozess übergeben. Dazu muss die Anwendung explizit diese Umgebungsvariablenzeichenfolgen erstellen, sie alphabetisch sortieren (da das System eine sortierte Umgebung verwendet), und sie in den Umgebungsblock einfügen. Normalerweise werden sie vor dem Umgebungsblock aufgrund der Sortierreihenfolge der Umgebungsblocks angezeigt.

Eine Möglichkeit zum Abrufen der aktuellen Verzeichnisinformationen für ein Laufwerk X besteht darin, den folgenden Aufruf auszuführen: GetFullPathName("X:", ...) Dies verhindert, dass eine Anwendung den Umgebungsblock scannen muss. Wenn der vollständige zurückgegebene Pfad X:ist, muss dieser Wert nicht als Umgebungsdaten übergeben werden, da das Stammverzeichnis das Standardverzeichnis für Laufwerk X eines neuen Prozesses ist.

Wenn ein Prozess mit CREATE_NEW_PROCESS_GROUP angegeben wird, wird ein impliziter Aufruf von SetConsoleCtrlHandler(NULL,TRUE) im Namen des neuen Prozesses vorgenommen; Dies bedeutet, dass der neue Prozess STRG+C deaktiviert hat. Dadurch können Shells STRG+C selbst verarbeiten und dieses Signal selektiv an Unterprozesse übergeben. STRG+BREAK ist nicht deaktiviert und kann verwendet werden, um die Prozess-/Prozessgruppe zu unterbrechen.

Standardmäßig bewirkt das Übergeben von TRUE als Wert des bInheritHandles-Parameters , dass alle vererbbaren Handle vom neuen Prozess geerbt werden. Dies kann für Anwendungen problematisch sein, die Prozesse aus mehreren Threads gleichzeitig erstellen, aber möchten, dass jeder Prozess verschiedene Handle erbt. Anwendungen können die UpdateProcThreadAttributeList-Funktion mit dem parameter PROC_THREAD_ATTRIBUTE_HANDLE_LIST verwenden, um eine Liste von Handle bereitzustellen, die von einem bestimmten Prozess geerbt werden sollen.

Sicherheitsbemerkungen

Der erste Parameter lpApplicationName kann NULL sein, in diesem Fall muss sich der ausführbare Name in der durch lpCommandLine verweisenden Leerzeichenzeichenfolge befinden. Wenn der Name der ausführbaren Datei oder des Pfads ein Leerzeichen enthält, besteht ein Risiko, dass eine andere ausführbare Datei aufgrund der Art und Weise ausgeführt werden kann, wie die Funktion Leerzeichen analysiert. Das folgende Beispiel ist gefährlich, da die Funktion versucht, "Program.exe" auszuführen, falls vorhanden, anstelle von "MyApp.exe".
	LPTSTR szCmdline = _tcsdup(TEXT("C:\\Program Files\\MyApp -L -S"));
	CreateProcess(NULL, szCmdline, /* ... */);

Wenn ein böswilliger Benutzer eine Anwendung namens "Program.exe" auf einem System erstellen wollte, führt jedes Programm, das createProcess mit dem Verzeichnis "Programme" falsch aufruft, diese Anwendung anstelle der beabsichtigten Anwendung aus.

Um dieses Problem zu vermeiden, übergeben Sie nicht NULL für lpApplicationName. Wenn Sie NULL für lpApplicationName übergeben, verwenden Sie Anführungszeichen um den ausführbaren Pfad in lpCommandLine, wie im folgenden Beispiel gezeigt.

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

Beispiele

Ein Beispiel finden Sie unter Erstellen von Prozessen.

Hinweis

Der Header "processthreadsapi.h" definiert CreateProcess als Alias, der automatisch die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante auswählt. Das Mischen der codierungsneutralen Aliase mit Code, der nicht codierungsneutral ist, kann zu Übereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.

Anforderungen

   
Unterstützte Mindestversion (Client) Windows XP [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile processthreadsapi.h (include Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2, Windows.h)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

Closehandle

ShellExecuteA

CreateProcessAsUser

CreateProcessWithLogonW

ExitProcess

GetCommandLine

GetEnvironmentStrings

GetExitCodeProcess

GetFullPathName

GetStartupInfo

OpenProcess

PROCESS_INFORMATION

Prozess- und Threadfunktionen

Prozesse

SECURITY_ATTRIBUTES

STARTUPINFO

STARTUPINFOEX

SetErrorMode

TerminateProcess

Waitforinputidle