次の方法で共有


CreateProcessA 関数 (processthreadsapi.h)

新しいプロセスとそのプライマリ スレッドを作成します。 新しいプロセスは、呼び出し元プロセスのセキュリティ コンテキストで実行されます。

呼び出し元のプロセスが別のユーザーを偽装している場合、新しいプロセスは、偽装トークンではなく、呼び出し元プロセスにトークンを使用します。 偽装トークンによって表されるユーザーのセキュリティ コンテキストで新しいプロセスを実行するには、CreateProcessAsUserA 関数 を使用するか、CreateProcessWithLogonW 関数します。

構文

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

パラメーター

[in, optional] lpApplicationName

実行するモジュールの名前。 このモジュールは、Windows ベースのアプリケーションにすることができます。 適切なサブシステムがローカル コンピューターで使用可能な場合は、他の種類のモジュール (MS-DOS や OS/2 など) を使用できます。

文字列は、実行するモジュールの完全なパスとファイル名を指定することも、部分的な名前を指定することもできます。 部分名の場合、関数は現在のドライブと現在のディレクトリを使用して仕様を完了します。 関数は検索パスを使用しません。 このパラメーターには、ファイル名拡張子を含める必要があります。既定の拡張機能は想定されません。

lpApplicationName パラメーターは、NULLできます。 その場合、モジュール名は、lpCommandLine 文字列内の最初の空白で区切られたトークンである必要があります。 スペースを含む長いファイル名を使用している場合は、引用符で囲まれた文字列を使用して、ファイル名の末尾と引数の開始位置を示します。それ以外の場合、ファイル名はあいまいです。 たとえば、"c:\program files\sub dir\program name" という文字列を考えてみます。 この文字列は、さまざまな方法で解釈できます。 システムは、次の順序で可能性を解釈しようとします。

  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

実行可能モジュールが 16 ビット アプリケーションの場合、lpApplicationName は NULLし、lpCommandLine が指す文字列 実行可能モジュールとその引数を指定する必要があります。

バッチ ファイルを実行するには、コマンド インタープリターを開始する必要があります。lpApplicationName cmd.exe に設定し、lpCommandLine を次の引数に設定します:/c とバッチ ファイルの名前。

大事な

MSRC エンジニアリング チームはこれに対してアドバイスします。 詳細については、「MS14-019 - .cmdまたは .bat ファイル によるバイナリ ハイジャックの修正」を参照してください。

[in, out, optional] lpCommandLine

実行するコマンド ライン。

この文字列の最大長は 32,767 文字 (Unicode 終端の null 文字を含む) です。 lpApplicationName が NULL場合、lpCommandLine モジュール名の部分は MAX_PATH 文字に制限されます。

この関数の Unicode バージョン (CreateProcessW) は、この文字列の内容を変更できます。 したがって、このパラメーターを読み取り専用メモリへのポインターにすることはできません (const 変数やリテラル文字列など)。 このパラメーターが定数文字列の場合、関数によってアクセス違反が発生する可能性があります。

lpCommandLine パラメーターには NULL を指定できます。 その場合、この関数は lpApplicationName 指す文字列をコマンド ラインとして使用します。

lpApplicationName lpCommandLine が非NULLの場合、実行するモジュール lpApplicationName が指す null 終端文字列、および lpCommandLine が指す null 終端文字列 コマンド ラインを指定します。 新しいプロセスでは、GetCommandLine を使用して、コマンド ライン全体を取得できます。 C で記述されたコンソール プロセスでは、argcargv 引数を使用してコマンド ラインを解析できます。 argv[0] はモジュール名であるため、C プログラマは通常、モジュール名をコマンド ラインの最初のトークンとして繰り返します。

lpApplicationName が NULL の場合、コマンド ラインの最初の空白区切りトークンでモジュール名を指定します。 スペースを含む長いファイル名を使用している場合は、引用符で囲まれた文字列を使用して、ファイル名の末尾と引数の開始位置を示します (lpApplicationName パラメーターの説明を参照してください)。 ファイル名に拡張子が含まれていない場合は、.exe が追加されます。 したがって、ファイル名拡張子が.com場合、このパラメーターには.com拡張子を含める必要があります。 ファイル名が拡張子のないピリオド (.) で終わる場合、またはファイル名にパスが含まれている場合、.exe は追加されません。 ファイル名にディレクトリ パスが含まれていない場合、システムは次の順序で実行可能ファイルを検索します。

  • アプリケーションの読み込み元ディレクトリ。
  • 親プロセスの現在のディレクトリ。
  • 32 ビットの Windows システム ディレクトリ。 GetSystemDirectoryA 関数 関数を使用して、このディレクトリのパスを取得します。
  • 16 ビットの Windows システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。 このディレクトリの名前は System です。
  • Windows ディレクトリ。 GetWindowsDirectoryA 関数 を使用して、このディレクトリのパスを取得します。
  • PATH 環境変数に一覧表示されているディレクトリ。 この関数は、アプリ パス レジストリ キーで指定されたアプリケーションごとのパスを検索しないことに注意してください。 このアプリケーションごとのパスを検索シーケンスに含めるには、ShellExecute 関数を使用します。

システムは、コマンド ライン文字列に終端の null 文字を追加して、ファイル名を引数から分離します。 これにより、内部処理のために元の文字列が 2 つの文字列に分割されます。

[in, optional] lpProcessAttributes

新しいプロセス オブジェクトに対して返されたハンドルを子プロセスによって継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインター。 lpProcessAttributes が NULL場合、ハンドルを継承できません。

構造体の lpSecurityDescriptor メンバーは、新しいプロセスのセキュリティ記述子を指定します。 lpProcessAttributes が NULL であるか、lpSecurityDescriptor が NULL場合、プロセスは既定のセキュリティ記述子を取得します。 プロセスの既定のセキュリティ記述子の ACL は、作成者のプライマリ トークンから取得されます。 Windows XP: プロセスの既定のセキュリティ記述子の ACL は、作成者のプライマリ トークンまたは偽装トークンから取得されます。 この動作は、WINDOWS XP SP2 および Windows Server 2003 で変更されました。

[in, optional] lpThreadAttributes

新しいスレッド オブジェクトに対して返されたハンドルを子プロセスによって継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインター。 lpThreadAttributes が NULL の場合、ハンドルを継承できません。

構造体の lpSecurityDescriptor メンバーは、メイン スレッドのセキュリティ記述子を指定します。 lpThreadAttributes が NULL であるか、lpSecurityDescriptor が NULL 場合、スレッドは既定のセキュリティ記述子を取得します。 スレッドの既定のセキュリティ記述子の ACL は、プロセス トークンから取得されます。 Windows XP: スレッドの既定のセキュリティ記述子の ACL は、作成者のプライマリ トークンまたは偽装トークンから取得されます。 この動作は、WINDOWS XP SP2 および Windows Server 2003 で変更されました。

[in] bInheritHandles

このパラメーターが TRUE の場合、呼び出し元プロセスの継承可能な各ハンドルは新しいプロセスによって継承されます。 パラメーターが FALSE の場合、ハンドルは継承されません。 継承されたハンドルは、元のハンドルと同じ値とアクセス権を持つことに注意してください。 継承可能なハンドルの詳細については、「解説」を参照してください。

ターミナル サービス: セッション間でハンドルを継承することはできません。 さらに、このパラメーターが TRUE の場合は、呼び出し元と同じセッションでプロセスを作成する必要があります。

Protected Process Light (PPL) プロセス: PPL 以外のプロセスから PPL プロセスへのPROCESS_DUP_HANDLEが許可されていないため、PPL プロセスが非 PPL プロセスを作成すると、汎用ハンドルの継承がブロックされます。 プロセスのセキュリティとアクセス権の の を参照してください

Windows 7: パラメーターが FALSE の場合でも、 STD_INPUT_HANDLE、STD_OUTPUT_HANDLE、およびSTD_ERROR_HANDLEが継承されます。

[in] dwCreationFlags

優先順位クラスとプロセスの作成を制御するフラグ。 値の一覧については、「プロセス作成フラグを参照してください。

このパラメーターは、プロセスのスレッドのスケジュールの優先順位を決定するために使用される、新しいプロセスの優先順位クラスも制御します。 値の一覧については、GetPriorityClassを参照してください。 優先度クラス フラグが指定されていない場合、作成プロセスの優先順位クラスが IDLE_PRIORITY_CLASS または BELOW_NORMAL_PRIORITY_CLASSでない限り、優先度クラスの既定値は NORMAL_PRIORITY_CLASS になります。 この場合、子プロセスは呼び出し元プロセスの既定の優先度クラスを受け取ります。

dwCreationFlags パラメーターの値が 0 の場合:

  • プロセスは、呼び出し元のエラー モードと親のコンソールの両方を継承します。
  • 新しいプロセスの環境ブロックには ANSI 文字が含まれていると見なされます (詳細については、lpEnvironment パラメーター 参照)。
  • 16 ビットの Windows ベースのアプリケーションは、共有 Virtual DOS マシン (VDM) で実行されます。

[in, optional] lpEnvironment

新しいプロセスに 環境ブロックへのポインター。 このパラメーターが NULL場合、新しいプロセスは呼び出し元プロセスの環境を使用します。

環境ブロックは、null で終わる文字列の null で終わるブロックで構成されます。 各文字列の形式は次のとおりです。

名前=\0

等号は区切り記号として使用されるため、環境変数の名前には使用しないでください。

環境ブロックには、Unicode 文字または ANSI 文字を含めることができます。 lpEnvironment 指す環境ブロックに Unicode 文字が含まれている場合は、dwCreationFlags CREATE_UNICODE_ENVIRONMENTが含まれていることを確認してください。

この関数の ANSI バージョン CreateProcessA は、プロセスの環境ブロックの合計サイズが 32,767 文字を超えると失敗します。

ANSI 環境ブロックは 2 つのゼロ バイトで終了されることに注意してください。最後の文字列の場合は 1 つ、もう 1 つはブロックを終了します。 Unicode 環境ブロックは、最後の文字列に対して 2 バイト、ブロックを終了するためにさらに 2 バイトの 4 つのゼロ バイトで終了されます。

[in, optional] lpCurrentDirectory

プロセスの現在のディレクトリへの完全なパス。 この文字列では、UNC パスを指定することもできます。

このパラメーターが NULL場合、新しいプロセスは呼び出し元のプロセスと同じ現在のドライブとディレクトリを持ちます。 (この機能は、主にアプリケーションを起動し、その初期ドライブと作業ディレクトリを指定する必要があるシェル用に提供されます。

[in] lpStartupInfo

STARTUPINFO または STARTUPINFOEX 構造体 へのポインター。

拡張属性を設定するには、STARTUPINFOEX 構造体を使用し、dwCreationFlags パラメーターにEXTENDED_STARTUPINFO_PRESENTを指定します。

STARTUPINFO または STARTUPINFOEX ハンドルは、必要なくなったときに、CloseHandle で閉じる必要があります。

大事な

呼び出し元は、STARTUPINFO の標準ハンドル フィールド 有効なハンドル値が含まれていることを確認する必要があります。 これらのフィールドは、dwFlags メンバーが STARTF_USESTDHANDLESを指定した場合でも、検証なしで子プロセスに変更されずにコピーされます。 値が正しくないと、子プロセスが不適切な動作やクラッシュを引き起こす可能性があります。 アプリケーション検証ツール ランタイム検証ツールを使用して、無効なハンドルを検出します。

[out] lpProcessInformation

新しいプロセスに関する識別情報を受け取る PROCESS_INFORMATION 構造体へのポインター。

PROCESS_INFORMATION のハンドルは、必要なくなったときに、CloseHandle で閉じる必要があります。

戻り値

関数が成功した場合、戻り値は 0 以外です。

関数が失敗した場合、戻り値は 0 です。 拡張エラー情報を取得するには、GetLastError呼び出します。

この関数は、プロセスの初期化が完了する前に返されることに注意してください。 必要な DLL が見つからないか、初期化に失敗した場合、プロセスは終了します。 プロセスの終了状態を取得するには、GetExitCodeProcess呼び出します。

備考

プロセスにはプロセス識別子が割り当てられます。 識別子は、プロセスが終了するまで有効です。 プロセスを識別するために使用することも、プロセスへのハンドルを開くために OpenProcess 関数で指定することもできます。 プロセスの初期スレッドにもスレッド識別子が割り当てられます。 OpenThread 関数で指定して、スレッドへのハンドルを開くことができます。 識別子は、スレッドが終了するまで有効であり、システム内のスレッドを一意に識別するために使用できます。 これらの識別子は、PROCESS_INFORMATION 構造体で返されます。

オペレーティング システムがプロセスに提供するコマンド ラインの実行可能ファイルの名前は、呼び出し元のプロセスが CreateProcess 関数に与えるコマンド ラインの名前と必ずしも同じではありません。 オペレーティング システムは、完全修飾パスなしで提供される実行可能ファイル名の先頭に完全修飾パスを付加できます。

呼び出し元のスレッドは、WaitForInputIdle 関数を使用して、新しいプロセスの初期化が完了し、入力が保留中でないユーザー入力を待機します。 これは、親プロセスと子プロセス間の同期に役立ちます。CreateProcess は、新しいプロセスが初期化を完了するのを待たずに戻るためです。 たとえば、作成プロセスでは、新しいプロセス 関連付けられたウィンドウを検索する前に、WaitForInputIdle を使用します。

プロセスをシャットダウンするには、ExitProcess 関数を使用することをお勧めします。この関数は、プロセスにアタッチされているすべての DLL に終了に近づく通知を送信するためです。 プロセスをシャットダウンするその他の方法では、アタッチされた DLL には通知されません。 スレッドが ExitProcess呼び出すと、プロセスの他のスレッドは、追加のコード (アタッチされた DLL のスレッド終了コードを含む) を実行する機会なしに終了されることに注意してください。 詳細については、「プロセスの終了 」を参照してください。

親プロセスでは、プロセスの作成時に子プロセスの環境変数を直接変更できます。 これは、プロセスが別のプロセスの環境設定を直接変更できる唯一の状況です。 詳細については、「環境変数の変更」を参照してください。

アプリケーションが環境ブロックを提供する場合、システム ドライブの現在のディレクトリ情報は新しいプロセスに自動的に反映されません。 たとえば、=C: という名前の環境変数があり、その値はドライブ C の現在のディレクトリです。アプリケーションは、現在のディレクトリ情報を新しいプロセスに手動で渡す必要があります。 そのためには、アプリケーションでこれらの環境変数文字列を明示的に作成し、それらをアルファベット順に並べ替え (システムが並べ替えられた環境を使用するため)、環境ブロックに配置する必要があります。 通常、環境ブロックの並べ替え順序により、環境ブロックの先頭に移動します。

ドライブ X の現在のディレクトリ情報を取得する方法の 1 つは、次の呼び出しを行う方法です: GetFullPathName("X:", ...). そのため、アプリケーションで環境ブロックをスキャンする必要がなくなります。 返される完全なパスが X: の場合、ルート ディレクトリは新しいプロセスのドライブ X の既定の現在のディレクトリであるため、その値を環境データとして渡す必要はありません。

CREATE_NEW_PROCESS_GROUP を指定してプロセスを作成すると、新しいプロセスの代わりに SetConsoleCtrlHandler(NULL,TRUE) への暗黙的な呼び出 しが行われます。これは、新しいプロセスで Ctrl + C が無効であることを意味します。 これにより、シェルは Ctrl + C 自体を処理し、そのシグナルをサブプロセスに選択的に渡すことができます。 Ctrl + BREAK は無効ではなく、プロセス/プロセス グループを中断するために使用できます。

既定では、bInheritHandles パラメーターの値として true 渡すと、継承可能なすべてのハンドルが新しいプロセスによって継承されます。 これは、複数のスレッドから同時にプロセスを作成するが、各プロセスが異なるハンドルを継承することを望むアプリケーションでは問題になる可能性があります。

アプリケーションでは、UpdateProcThreadAttributeList 関数を PROC_THREAD_ATTRIBUTE_HANDLE_LIST パラメーターと共に使用して、特定のプロセスによって継承されるハンドルの一覧を提供できます。

セキュリティに関する備考

最初のパラメーター lpApplicationNameは NULLできます。この場合、実行可能ファイル名は、lpCommandLine指す空白で区切られた文字列に含める必要があります。 実行可能ファイルまたはパス名にスペースがある場合、関数がスペースを解析する方法により、別の実行可能ファイルが実行される可能性があります。 次の例は、関数が "MyApp.exe" ではなく "Program.exe" (存在する場合) を実行しようとするため、危険です。

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

悪意のあるユーザーがシステムで "Program.exe" という名前のアプリケーションを作成した場合、Program Files ディレクトリを使用して CreateProcess を誤って呼び出すプログラムは、目的のアプリケーションではなく、このアプリケーションを実行します。

この問題を回避するには、lpApplicationNamenull 渡さないでください。 lpApplicationNameNULL を渡す場合は、次の例に示すように、lpCommandLineの実行可能パスを引用符で囲みます。

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

例については、「プロセスの作成 」を参照してください。

手記

processthreadsapi.h ヘッダーは、Unicode プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして CreateProcess を定義します。 エンコードに依存しないエイリアスをエンコードに依存しないコードと組み合わせて使用すると、コンパイルエラーやランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「関数プロトタイプの 規則」を参照してください。

必要条件

要件 価値
サポートされる最小クライアント Windows XP [デスクトップ アプリ |UWP アプリ]
サポートされる最小サーバー Windows Server 2003 [デスクトップ アプリ |UWP アプリ]
ターゲット プラットフォーム の ウィンドウズ
ヘッダー processthreadsapi.h (Windows Server 2003、Windows Vista、Windows 7、Windows Server 2008 Windows Server 2008 R2 の Windows.h を含む)
ライブラリ Kernel32.lib
DLL Kernel32.dll

関連項目

CloseHandle の

ShellExecuteA

CreateProcessAsUser の

CreateProcessWithLogonW の

ExitProcess の

GetCommandLine の

GetEnvironmentStrings の

GetExitCodeProcess の

GetFullPathName の

GetStartupInfo の

OpenProcess を する

PROCESS_INFORMATION

プロセス関数とスレッド関数の

プロセスの

SECURITY_ATTRIBUTES

STARTUPINFO を する

STARTUPINFOEX を する

SetErrorMode の

TerminateProcess の

WaitForInputIdle の