CreateProcessW-Funktion (processthreadsapi.h)

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

Wenn der aufrufende Prozess die Identität eines anderen Benutzers angibt, verwendet der neue Prozess das Token für den aufrufenden Prozess, nicht das Identitätswechseltoken. Um den neuen Prozess im Sicherheitskontext des Benutzers auszuführen, der durch das Identitätswechseltoken dargestellt wird, verwenden Sie die Funktion CreateProcessAsUser oder CreateProcessWithLogonW .

Syntax

BOOL CreateProcessW(
  [in, optional]      LPCWSTR               lpApplicationName,
  [in, out, optional] LPWSTR                lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCWSTR               lpCurrentDirectory,
  [in]                LPSTARTUPINFOW        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
);

Parameter

[in, optional] lpApplicationName

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

Die Zeichenfolge kann den vollständigen Pfad und Dateinamen des auszuführenden Moduls oder einen Teilnamen angeben. Bei einem Teilnamen verwendet die Funktion das aktuelle Laufwerk und das aktuelle Verzeichnis, um die Spezifikation zu vervollständigen. Die Funktion verwendet nicht den Suchpfad. 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 leerzeichentrennte Token in der lpCommandLine-Zeichenfolge sein. Wenn Sie einen langen Dateinamen verwenden, der ein Leerzeichen enthält, verwenden Sie Zeichenfolgen in Anführungszeichen, um anzugeben, wo der Dateiname endet und die Argumente beginnen. Andernfalls ist der Dateiname mehrdeutig. Betrachten Sie beispielsweise die Zeichenfolge "c:\program files\sub dir\program name". Diese Zeichenfolge kann auf verschiedene Arten interpretiert werden. Das System versucht, die Möglichkeiten in der folgenden Reihenfolge zu interpretieren:

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

Wenn es sich bei dem ausführbaren Modul um eine 16-Bit-Anwendung handelt, sollte lpApplicationNameNULL sein, und die Zeichenfolge, auf die 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 und lpCommandLine auf die folgenden Argumente fest: /c plus dem Namen der Batchdatei.

[in, out, optional] lpCommandLine

Die auszuführende Befehlszeile.

Die maximale Länge dieser Zeichenfolge beträgt 32.767 Zeichen, einschließlich des Unicode-Endzeichens NULL. Wenn lpApplicationNameNULL ist, ist der Modulnamenteil 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 auf schreibgeschützten Arbeitsspeicher (z. B. eine const-Variable oder eine Literalzeichenfolge) sein. Wenn es sich bei diesem Parameter um eine konstante Zeichenfolge handelt, kann die Funktion zu einer Zugriffsverletzung führen.

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

Wenn sowohl lpApplicationName als auch lpCommandLine nicht NULL sind, gibt die von lpApplicationName auf null beendete Zeichenfolge das auszuführende Modul an, und die null-beendete Zeichenfolge, auf die von lpCommandLine verwiesen wird, gibt die Befehlszeile an. Der neue Prozess kann GetCommandLine verwenden, um die gesamte Befehlszeile abzurufen. In C geschriebene Konsolenprozesse können die Argumente argc und argv verwenden, um die Befehlszeile zu analysieren. Da argv[0] der Modulname ist, wiederholen C-Programmierer in der Regel den Modulnamen als erstes Token in der Befehlszeile.

Wenn lpApplicationName NULL ist, gibt das erste leerzeichentrennte Token der Befehlszeile den Modulnamen an. Wenn Sie einen langen Dateinamen verwenden, der ein Leerzeichen enthält, verwenden Sie Zeichenfolgen in Anführungszeichen, um anzugeben, wo der Dateiname endet und die Argumente beginnen (siehe Erklärung für den lpApplicationName-Parameter ). Wenn der Dateiname keine Erweiterung enthält, wird .exe angefügt. Wenn die Dateinamenerweiterung .com ist, muss dieser Parameter daher die erweiterung .com enthalten. Wenn der Dateiname mit einem Punkt (.) ohne Erweiterung endet oder der Dateiname einen Pfad enthält, wird .exe nicht angefügt. Wenn der Dateiname keinen Verzeichnispfad enthält, sucht das System in der folgenden Reihenfolge nach der ausführbaren Datei:

  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 er wird durchsucht. Der Name dieses Verzeichnisses lautet System.
  5. Das Windows-Verzeichnis. Verwenden Sie die GetWindowsDirectory-Funktion , um den Pfad dieses Verzeichnisses abzurufen.
  6. Die Verzeichnisse, die in der PATH-Umgebungsvariablen aufgeführt sind. Beachten Sie, dass diese Funktion nicht den anwendungsspezifischen Pfad durchsucht, der vom Registrierungsschlüssel App-Pfad angegeben wird. Verwenden Sie die Funktion ShellExecute , um diesen Anwendungspfad in die Suchsequenz einzuschließen.
Das System fügt der Befehlszeilenzeichenfolge ein abschließendes NULL-Zeichen hinzu, um den Dateinamen von den Argumenten zu trennen. Dadurch wird die ursprüngliche Zeichenfolge für die interne Verarbeitung in zwei Zeichenfolgen unterteilt.

[in, optional] lpProcessAttributes

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

Der lpSecurityDescriptor-Member der -Struktur gibt einen Sicherheitsdeskriptor für den neuen Prozess an. Wenn lpProcessAttributes NULL oder lpSecurityDescriptorNULL ist, ruft der Prozess einen Standardsicherheitsdeskriptor ab. Die ACLs im Standardsicherheitsdeskriptor für einen Prozess stammen vom primären Token des Erstellers. Windows XP: Die ACLs im Standardsicherheitsdeskriptor für einen Prozess stammen aus dem primären Token oder dem Identitätswechseltoken des Erstellers. Dieses Verhalten hat sich mit Windows XP mit SP2 und Windows Server 2003 geändert.

[in, optional] lpThreadAttributes

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

Der lpSecurityDescriptor-Member der -Struktur gibt einen Sicherheitsdeskriptor für den Standard Thread an. Wenn lpThreadAttributes NULL oder lpSecurityDescriptor NULL ist, erhält der Thread einen Standardsicherheitsdeskriptor. 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 Token oder dem Identitätswechseltoken des Erstellers. Dieses Verhalten hat sich mit Windows XP mit SP2 und Windows Server 2003 geändert.

[in] bInheritHandles

Wenn dieser Parameter TRUE ist, wird jedes vererbbare Handle im aufrufenden Prozess vom neuen Prozess geerbt. Wenn der Parameter FALSE ist, werden die Handles nicht geerbt. Beachten Sie, dass geerbte Handles den gleichen Wert und dieselben Zugriffsrechte wie die ursprünglichen Handles haben. Weitere Informationen zu vererbbaren Handles finden Sie unter Hinweise.

Terminaldienste: Sie können handles nicht sitzungsübergreifend erben. Wenn dieser Parameter TRUE ist, müssen Sie den Prozess in derselben Sitzung wie der Aufrufer erstellen.

Geschützte Prozesslichtprozesse (PPL): Die generische Handlevererbung wird blockiert, wenn ein PPL-Prozess einen Nicht-PPL-Prozess erstellt, da PROCESS_DUP_HANDLE von einem Nicht-PPL-Prozess in einen PPL-Prozess nicht zulässig ist. Weitere Informationen finden Sie unter Prozesssicherheit und Zugriffsrechte.

[in] dwCreationFlags

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

Dieser Parameter steuert auch die Prioritätsklasse des neuen Prozesses, die verwendet wird, um die Planungsprioritäten der Prozessthreads zu bestimmen. Eine Liste der Werte finden Sie unter GetPriorityClass. Wenn keines der Prioritätsklassenflags angegeben ist, wird die Prioritätsklasse standardmäßig auf NORMAL_PRIORITY_CLASS festgelegt , es sei denn, die Prioritätsklasse des Erstellungsprozesses ist IDLE_PRIORITY_CLASS oder BELOW_NORMAL_PRIORITY_CLASS. In diesem Fall erhält der untergeordnete Prozess die Standardprioritätsklasse des aufrufenden Prozesses.

Wenn der dwCreationFlags-Parameter den Wert 0 aufweist:

  • Der Prozess erbt sowohl den Fehlermodus des Aufrufers als auch die Konsole des übergeordneten Elements.
  • Es wird davon ausgegangen, dass der Umgebungsblock für den neuen Prozess ANSI-Zeichen enthält (weitere Informationen finden Sie unter lpEnvironment-Parameter ).
  • Eine 16-Bit-Windows-basierte 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 aufrufenden Prozesses.

Ein Umgebungsblock besteht aus einem NULL-beendeten Block von Zeichenfolgen, die null beendet wurden. Jede Zeichenfolge hat die folgende Form:

Namen=value\0

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

Ein Umgebungsblock kann entweder Unicode- oder ANSI-Zeichen enthalten. Wenn der Umgebungsblock, auf den lpEnvironment verweist, Unicode-Zeichen enthält, stellen Sie sicher, dass dwCreationFlagsCREATE_UNICODE_ENVIRONMENT enthält.

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

Beachten Sie, dass ein ANSI-Umgebungsblock mit zwei Nullbytes beendet wird: eines für die letzte Zeichenfolge und ein weiteres zum Beenden des Blocks. Ein Unicode-Umgebungsblock wird durch vier Nullbytes 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, verfügt der neue Prozess über dasselbe aktuelle Laufwerk und Verzeichnis wie der aufrufende Prozess. (Dieses Feature wird in erster Linie für Shells bereitgestellt, die eine Anwendung starten und deren Anfangslaufwerk und Arbeitsverzeichnis angeben müssen.)

[in] lpStartupInfo

Ein Zeiger auf eine STARTUPINFO - oder STARTUPINFOEX-Struktur .

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

Handles 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 Standardhandlefelder in STARTUPINFO gültige Handlewerte enthalten. Diese Felder werden unverändert in den untergeordneten Prozess kopiert, auch wenn der dwFlags-MemberSTARTF_USESTDHANDLES angibt. Falsche Werte können dazu führen, dass sich der untergeordnete Prozess falsch benimmt oder abstürzt. Verwenden Sie das Application Verifier-Laufzeitüberprüfungstool , um ungültige Handles zu erkennen.
 

[out] lpProcessInformation

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

Handles 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 die Initialisierung des Prozesses abgeschlossen ist. Wenn eine erforderliche DLL nicht gefunden werden kann oder nicht initialisiert werden kann, wird der Prozess beendet. Rufen Sie GetExitCodeProcess auf, um die beendigung status eines Prozesses zu erhalten.

Hinweise

Dem Prozess wird ein 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 werden, um ein Handle für den Prozess zu öffnen. Dem anfänglichen Thread im Prozess wird auch ein Threadbezeichner zugewiesen. Es kann in der OpenThread-Funktion angegeben werden, um ein Handle für den Thread zu öffnen. Der Bezeichner ist gültig, bis der Thread beendet wird, und kann verwendet werden, 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 vom Betriebssystem für einen Prozess bereitgestellt wird, ist nicht unbedingt mit dem Namen in der Befehlszeile identisch, die der aufrufende Prozess der CreateProcess-Funktion bereitstellt. Das Betriebssystem kann einem ausführbaren Namen, der ohne vollqualifizierten Pfad bereitgestellt wird, einen vollqualifizierten Pfad voranstellen.

Der aufrufende Thread kann die WaitForInputIdle-Funktion verwenden, um zu warten, bis der neue Prozess seine Initialisierung abgeschlossen hat und auf Benutzereingaben wartet, ohne dass eine 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 seine Initialisierung abgeschlossen hat. Beispielsweise verwendet der Erstellungsprozess WaitForInputIdle , bevor versucht wird, ein Fenster zu finden, das dem neuen Prozess zugeordnet ist.

Die bevorzugte Möglichkeit zum Herunterfahren eines Prozesses ist die Verwendung der ExitProcess-Funktion , da diese Funktion eine Benachrichtigung über die bevorstehende Beendigung an alle 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 Threadabschlusscodes der 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, in der 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 namens =C: deren Wert das aktuelle Verzeichnis auf Laufwerk C ist. Eine Anwendung muss die aktuellen Verzeichnisinformationen manuell an den neuen Prozess übergeben. Dazu muss die Anwendung diese Umgebungsvariablenzeichenfolgen explizit erstellen, alphabetisch sortieren (da das System eine sortierte Umgebung verwendet) und in den Umgebungsblock einfügen. In der Regel werden sie aufgrund der Sortierreihenfolge des Umgebungsblocks an der Vorderseite des Umgebungsblockblocks angezeigt.

Eine Möglichkeit, die aktuellen Verzeichnisinformationen für ein Laufwerk X abzurufen, besteht darin, den folgenden Aufruf auszuführen: GetFullPathName("X:", ...). Dadurch wird vermieden, dass eine Anwendung den Umgebungsblock überprüfen muss. Wenn der vollständige Zurückgegebene Pfad X:ist, ist es nicht erforderlich, diesen Wert als Umgebungsdaten zu übergeben, da das Stammverzeichnis das aktuelle Standardverzeichnis für Laufwerk X eines neuen Prozesses ist.

Wenn ein Prozess mit CREATE_NEW_PROCESS_GROUP angegeben wird, wird im Namen des neuen Prozesses ein impliziter Aufruf von SetConsoleCtrlHandler(NULL,TRUE) durchgeführt. Dies bedeutet, dass für den neuen Prozess STRG+C deaktiviert ist. 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 den Prozess/die Prozessgruppe zu unterbrechen.

Standardmäßig bewirkt die Übergabe von TRUE als Wert des bInheritHandles-Parameters , dass alle vererbbaren Handles vom neuen Prozess geerbt werden. Dies kann für Anwendungen problematisch sein, die Prozesse aus mehreren Threads gleichzeitig erstellen, aber von jedem Prozess unterschiedliche Handles erben möchten. Anwendungen können die UpdateProcThreadAttributeList-Funktion mit dem parameter PROC_THREAD_ATTRIBUTE_HANDLE_LIST verwenden, um eine Liste der Handles 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 leerzeichentrennten Zeichenfolge befinden, auf die von lpCommandLine verwiesen wird. Wenn die ausführbare Datei oder der Pfadname ein Leerzeichen enthält, besteht aufgrund der Art und Weise, wie die Funktion Leerzeichen analysiert, das Risiko, dass eine andere ausführbare Datei ausgeführt werden kann. Das folgende Beispiel ist gefährlich, da die Funktion versucht, "Program.exe" anstelle von "MyApp.exe" auszuführen, sofern vorhanden.
	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 würde, führt jedes Programm, das CreateProcess fälschlicherweise über das Verzeichnis Programme aufruft, diese Anwendung anstelle der beabsichtigten Anwendung aus.

Um dieses Problem zu vermeiden, übergeben Sie null nicht 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 die ANSI- oder Unicode-Version dieser Funktion basierend auf der Definition der UNICODE-Präprozessorkonstante automatisch auswählt. Das Mischen der Verwendung des codierungsneutralen Alias mit Code, der nicht Codierungsneutral ist, kann zu Nichtübereinstimmungen führen, die zu Kompilierungs- oder Laufzeitfehlern führen. Weitere Informationen finden Sie unter Konventionen für Funktionsprototypen.

Anforderungen

Anforderung Wert
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 (enthalten Windows.h unter Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2)
Bibliothek Kernel32.lib
DLL Kernel32.dll

Siehe auch

CloseHandle

ShellExecuteW

CreateProcessAsUser

CreateProcessWithLogonW

ExitProcess

GetCommandLine

GetEnvironmentStrings

GetExitCodeProcess

GetFullPathName

GetStartupInfo

OpenProcess

PROCESS_INFORMATION

Prozess- und Threadfunktionen

Prozesse

SECURITY_ATTRIBUTES

STARTUPINFO

STARTUPINFOEX

SetErrorMode

TerminateProcess

Waitforinputidle