CreateProcessAsUserW 関数 (processthreadsapi.h)
新しいプロセスとそのプライマリ スレッドを作成します。 新しいプロセスは、指定されたトークンによって表されるユーザーのセキュリティ コンテキストで実行されます。
通常、CreateProcessAsUser 関数を呼び出すプロセスには SE_INCREASE_QUOTA_NAME 特権が必要であり、トークンが割り当てできない場合は SE_ASSIGNPRIMARYTOKEN_NAME 特権が必要になる場合があります。 この関数が
構文
BOOL CreateProcessAsUserW(
[in, optional] HANDLE hToken,
[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
);
パラメーター
[in, optional] hToken
ユーザーを表すプライマリ トークンのハンドル。 ハンドルには、TOKEN_QUERY、TOKEN_DUPLICATE、および TOKEN_ASSIGN_PRIMARY アクセス権が必要です。 詳細については、「Access-Token オブジェクトのアクセス権を
指定したユーザーを表すプライマリ トークンを取得するには、LogonUser 関数を呼び出します。 または、DuplicateTokenEx 関数を呼び出して、偽装トークンをプライマリ トークンに変換することもできます。 これにより、クライアントを偽装しているサーバー アプリケーションは、クライアントのセキュリティ コンテキストを持つプロセスを作成できます。
hToken
ターミナル サービス: トークンで指定されたセッションでプロセスが実行されます。 既定では、これは LogonUser
[in, optional] lpApplicationName
実行するモジュールの名前。 このモジュールは、Windows ベースのアプリケーションにすることができます。 適切なサブシステムがローカル コンピューターで使用可能な場合は、他の種類のモジュール (MS-DOS や OS/2 など) を使用できます。
文字列は、実行するモジュールの完全なパスとファイル名を指定することも、部分的な名前を指定することもできます。 部分名の場合、関数は現在のドライブと現在のディレクトリを使用して仕様を完了します。 関数は検索パスを使用しません。 このパラメーターには、ファイル名拡張子を含める必要があります。既定の拡張機能は想定されません。
[in, out, optional] lpCommandLine
実行するコマンド ライン。 この文字列の最大長は 32K 文字です。 lpApplicationName
この関数の Unicode バージョン CreateProcessAsUserWは、この文字列の内容を変更できます。 したがって、このパラメーターを読み取り専用メモリへのポインターにすることはできません (const 変数やリテラル文字列など)。 このパラメーターが定数文字列の場合、関数によってアクセス違反が発生する可能性があります。
lpApplicationName
lpApplicationName
- アプリケーションの読み込み元ディレクトリ。
- 親プロセスの現在のディレクトリ。
- 32 ビットの Windows システム ディレクトリ。 GetSystemDirectory 関数を使用して、このディレクトリのパスを取得します。
- 16 ビットの Windows システム ディレクトリ。 このディレクトリのパスを取得する関数はありませんが、検索されます。
- Windows ディレクトリ。 GetWindowsDirectory 関数を使用して、このディレクトリのパスを取得します。
- PATH 環境変数に一覧表示されているディレクトリ。 この関数は、アプリ パス レジストリ キーで指定されたアプリケーションごとのパスを検索しないことに注意してください。 このアプリケーションごとのパスを検索シーケンスに含めるには、ShellExecute 関数を使用します。
[in, optional] lpProcessAttributes
新しいプロセス オブジェクトのセキュリティ記述子を指定し、子プロセスが返されたハンドルをプロセスに継承できるかどうかを判断する SECURITY_ATTRIBUTES 構造体へのポインター。 lpProcessAttributes
[in, optional] lpThreadAttributes
新しいスレッド オブジェクトのセキュリティ記述子を指定し、子プロセスが返されたハンドルをスレッドに継承できるかどうかを判断する、SECURITY_ATTRIBUTES 構造体へのポインター。 lpThreadAttributes が NULL
[in] bInheritHandles
このパラメーターが TRUE
ターミナル サービス: セッション間でハンドルを継承することはできません。 さらに、このパラメーターが TRUE
Protected Process Light (PPL) プロセス: PPL 以外のプロセスから PPL プロセスへのPROCESS_DUP_HANDLEが許可されていないため、PPL プロセスが非 PPL プロセスを作成すると、汎用ハンドルの継承がブロックされます。 プロセスのセキュリティとアクセス権の の
[in] dwCreationFlags
優先順位クラスとプロセスの作成を制御するフラグ。 値の一覧については、「プロセス作成フラグ
このパラメーターは、プロセスのスレッドのスケジュールの優先順位を決定するために使用される、新しいプロセスの優先順位クラスも制御します。 値の一覧については、GetPriorityClass
dwCreationFlags パラメーターの値が 0 の場合:
- プロセスは、呼び出し元のエラー モードと親のコンソールの両方を継承します。
- 新しいプロセスの環境ブロックには ANSI 文字が含まれていると見なされます (詳細については、lpEnvironment パラメーター
参照)。 - 16 ビットの Windows ベースのアプリケーションは、共有 Virtual DOS マシン (VDM) で実行されます。
[in, optional] lpEnvironment
新しいプロセスの環境ブロックへのポインター。 このパラメーターが NULL
環境ブロックは、null で終わる文字列の null で終わるブロックで構成されます。 各文字列の形式は次のとおりです。
名前=値\0
等号は区切り記号として使用されるため、環境変数の名前には使用しないでください。
環境ブロックには、Unicode 文字または ANSI 文字を含めることができます。 lpEnvironment
この関数の ANSI バージョン CreateProcessAsUserA、プロセスの環境ブロックの合計サイズが 32,767 文字を超えると失敗します。
ANSI 環境ブロックは 2 つのゼロ バイトで終了されることに注意してください。最後の文字列の場合は 1 つ、もう 1 つはブロックを終了します。 Unicode 環境ブロックは、最後の文字列に対して 2 バイト、ブロックを終了するためにさらに 2 バイトの 4 つのゼロ バイトで終了されます。
Windows Server 2003 および Windows XP: ユーザーとシステム環境変数の組み合わせのサイズが 8192 バイトを超える場合、CreateProcessAsUser によって作成されたプロセス、親プロセスによって関数に渡された環境ブロックで実行されなくなります。 代わりに、子プロセスは、CreateEnvironmentBlock 関数によって返される環境ブロックで実行されます。
特定のユーザーの環境ブロックのコピーを取得するには、CreateEnvironmentBlock 関数を使用します。
[in, optional] lpCurrentDirectory
プロセスの現在のディレクトリへの完全なパス。 この文字列では、UNC パスを指定することもできます。
このパラメーターが NULL の場合、新しいプロセスの現在のドライブとディレクトリは呼び出し元プロセスと同じになります。 (この機能は、主にアプリケーションを起動し、その初期ドライブと作業ディレクトリを指定する必要があるシェル用に提供されます。
[in] lpStartupInfo
ユーザーは、指定されたウィンドウ ステーションとデスクトップの両方にフル アクセスできる必要があります。 プロセスを対話形式にする場合は、winsta0\default を指定します。 lpDesktop メンバーが NULL の場合、新しいプロセスは親プロセスのデスクトップステーションとウィンドウステーションを継承します。 このメンバーが空の文字列 "" の場合、新しいプロセスは、「ウィンドウ ステーションへの接続の処理 に関するページで説明されている規則を使用してウィンドウ ステーションに接続します。
拡張属性を設定するには、STARTUPINFOEX 構造体を使用し、dwCreationFlags パラメーターに EXTENDED_STARTUPINFO_PRESENT を指定します。
STARTUPINFO または
[out] lpProcessInformation
新しいプロセスに関する識別情報を受け取る PROCESS_INFORMATION 構造体へのポインター。
PROCESS_INFORMATION のハンドルは、必要なくなったときに、CloseHandle で閉じる必要があります。
戻り値
関数が成功した場合、戻り値は 0 以外です。
関数が失敗した場合、戻り値は 0 です。 拡張エラー情報を取得するには、GetLastError
この関数は、プロセスの初期化が完了する前に返されることに注意してください。 必要な DLL が見つからないか、初期化に失敗した場合、プロセスは終了します。 プロセスの終了状態を取得するには、GetExitCodeProcess
備考
CreateProcessAsUser
既定では、CreateProcessAsUser
CreateProcessAsUser
lpEnvironment パラメーターが NULL の場合、新しいプロセスは呼び出し元プロセスの環境を継承します。
CreateProcessAsUser
CreateProcessAsUser
プロセスにはプロセス識別子が割り当てられます。 識別子は、プロセスが終了するまで有効です。 プロセスを識別するために使用することも、プロセスへのハンドルを開くために OpenProcess 関数で指定することもできます。 プロセスの初期スレッドにもスレッド識別子が割り当てられます。 OpenThread 関数で指定して、スレッドへのハンドルを開くことができます。 識別子は、スレッドが終了するまで有効であり、システム内のスレッドを一意に識別するために使用できます。 これらの識別子は、PROCESS_INFORMATION 構造体で返されます。
呼び出し元のスレッドは、WaitForInputIdle 関数を使用して、新しいプロセスの初期化が完了し、入力が保留中でないユーザー入力を待機します。 これは、親プロセスと子プロセスの間の同期に役立ちます。CreateProcessAsUser
プロセスをシャットダウンするには、ExitProcess 関数を使用することをお勧めします。この関数は、プロセスにアタッチされているすべての DLL に終了に近づく通知を送信するためです。 プロセスをシャットダウンするその他の方法では、アタッチされた DLL には通知されません。 スレッドが ExitProcess
既定では、
セキュリティに関する備考
LPTSTR szCmdline[] = _tcsdup(TEXT("C:\\Program Files\\MyApp"));
CreateProcessAsUser(hToken, NULL, szCmdline, /*...*/ );
悪意のあるユーザーが "Program.exe" という名前のアプリケーションをシステムに作成した場合、Program Files ディレクトリを使用 CreateProcessAsUser を誤って呼び出すプログラムは、目的のアプリケーションではなく、このアプリケーションを実行します。
この問題を回避するには、lpApplicationName
LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\""));
CreateProcessAsUser(hToken, NULL, szCmdline, /*...*/);
PowerShell: CreateProcessAsUser 関数を使用して PowerShell バージョン 2.0 でコマンドレットを実装すると、このコマンドレットはファンインとファンアウトの両方のリモート セッションで正しく動作します。 ただし、セキュリティシナリオによっては、CreateProcessAsUser で実装されたコマンドレットは、ファンイン リモート セッションの PowerShell バージョン 3.0 でのみ正しく動作します。クライアントセキュリティ特権が不十分なため、ファンアウトリモートセッションは失敗します。 PowerShell バージョン 3.0 でファンインとファンアウトの両方のリモート セッションに対して機能するコマンドレットを実装するには、CreateProcess 関数を使用します。
例
例については、「対話型クライアント プロセスの開始
手記
processthreadsapi.h ヘッダーは、Unicode プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして CreateProcessAsUser を定義します。 エンコードに依存しないエイリアスをエンコードに依存しないコードと組み合わせて使用すると、コンパイルエラーやランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「関数プロトタイプの 規則」を参照してください。
必要条件
要件 | 価値 |
---|---|
サポートされる最小クライアント | Windows XP [デスクトップ アプリのみ] |
サポートされる最小サーバー | Windows Server 2003 [デスクトップ アプリのみ] |
ターゲット プラットフォーム の |
ウィンドウズ |
ヘッダー | processthreadsapi.h (Windows.h を含む) |
ライブラリ | Advapi32.lib |
DLL | Advapi32.dll |
関連項目
CloseHandle の
CreateEnvironmentBlock の
CreateProcess の
CreateProcessWithLogonW の
ExitProcess の
GetEnvironmentStrings の
GetExitCodeProcess の
GetStartupInfo の
LoadUserProfile の
SHCreateProcessAsUserW を
STARTUPINFO を
STARTUPINFOEX を
SetErrorMode の
WaitForInputIdle の