CreateProcessAsUserW

新しいプロセスとそのプライマリスレッドを作成する。新しいプロセスは、指定したトークンが表すユーザーのセキュリティコンテキストで動作する。(Unicode)

CreateProcessAsUserW hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation

hToken : [intptr] ユーザーを表すプライマリトークンへのハンドル。ハンドルは TOKEN_QUERY、TOKEN_DUPLICATE、TOKEN_ASSIGN_PRIMARY アクセス権を持っている必要がある。詳細は「Access Rights for Access-Token Objects」を参照のこと。トークンが表すユーザーは、lpApplicationName または lpCommandLine パラメータで指定されたアプリケーションに対して読み取りおよび実行アクセス権を持っている必要がある。
lpApplicationName : [wstr] 実行するモジュールの名前。このモジュールは Windows ベースのアプリケーションでもよい。ローカルコンピュータで適切なサブシステムが利用可能であれば、MS-DOS や OS/2 などの他の種類のモジュールでもよい。
lpCommandLine : [wstr] 実行するコマンドライン。この文字列の最大長は 32K 文字である。lpApplicationName が NULL の場合、lpCommandLine のモジュール名部分は MAX_PATH 文字に制限される。本関数の Unicode 版 CreateProcessAsUserW はこの文字列の内容を変更することがある。したがって、このパラメータは読み取り専用メモリ(const 変数やリテラル文字列など)へのポインタであってはならない。このパラメータが定数文字列の場合、関数はアクセス違反を引き起こすことがある。lpCommandLine パラメータは NULL にできる。その場合、関数は lpApplicationName が指す文字列をコマンドラインとして使用する。lpApplicationName と lpCommandLine が両方とも NULL でない場合、*lpApplicationName が実行するモジュールを指定し、*lpCommandLine がコマンドラインを指定する。新しいプロセスは GetCommandLine を使用してコマンドライン全体を取得できる。C で書かれたコンソールプロセスは argc と argv 引数を使ってコマンドラインを解析できる。argv[0] はモジュール名であるため、C プログラマは通常コマンドラインの最初のトークンとしてモジュール名を繰り返す。lpApplicationName が NULL の場合、コマンドラインの最初の空白区切りトークンがモジュール名を指定する。空白を含む長いファイル名を使用する場合は、ファイル名の終わりと引数の始まりを示すために引用符で囲む(lpApplicationName パラメータの説明を参照)。ファイル名に拡張子が含まれない場合、.exe が付加される。したがって、ファイル名の拡張子が .com の場合、このパラメータには .com 拡張子を含める必要がある。拡張子のないピリオド (.) で終わるファイル名、またはパスを含むファイル名の場合、.exe は付加されない。ファイル名にディレクトリパスが含まれない場合、システムは以下の順序で実行可能ファイルを検索する:
lpProcessAttributes : [var] 新しいプロセスオブジェクトのセキュリティ記述子を指定し、子プロセスがプロセスへの返されたハンドルを継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインタ。lpProcessAttributes が NULL または lpSecurityDescriptor が NULL の場合、プロセスは既定のセキュリティ記述子を取得し、ハンドルは継承できない。既定のセキュリティ記述子は、hToken パラメータで参照されるユーザーのものである。このセキュリティ記述子は呼び出し元へのアクセスを許可しない場合があり、その場合、プロセスは実行後に再度開けないことがある。プロセスハンドルは有効で、引き続き完全なアクセス権を持つ。
lpThreadAttributes : [var] 新しいスレッドオブジェクトのセキュリティ記述子を指定し、子プロセスがスレッドへの返されたハンドルを継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインタ。lpThreadAttributes が NULL または lpSecurityDescriptor が NULL の場合、スレッドは既定のセキュリティ記述子を取得し、ハンドルは継承できない。既定のセキュリティ記述子は、hToken パラメータで参照されるユーザーのものである。このセキュリティ記述子は呼び出し元へのアクセスを許可しない場合がある。
bInheritHandles : [int] このパラメータが TRUE の場合、呼び出し元プロセス内の継承可能なハンドルはそれぞれ新しいプロセスに継承される。FALSE の場合、ハンドルは継承されない。継承されたハンドルは元のハンドルと同じ値およびアクセス権を持つことに注意。継承可能なハンドルに関する追加の議論については「注釈」を参照のこと。ターミナルサービス: セッションをまたいでハンドルを継承することはできない。また、このパラメータが TRUE の場合、呼び出し元と同じセッション内でプロセスを作成する必要がある。Protected Process Light (PPL) プロセス: PPL プロセスが非 PPL プロセスを作成する場合、非 PPL プロセスから PPL プロセスへの PROCESS_DUP_HANDLE が許可されないため、一般的なハンドル継承はブロックされる。「Process Security and Access Rights」を参照のこと。
dwCreationFlags : [int] プライオリティクラスとプロセスの作成を制御するフラグ。値の一覧は「Process Creation Flags」を参照のこと。
lpEnvironment : [intptr] 新しいプロセスの環境ブロックへのポインタ。このパラメータが NULL の場合、新しいプロセスは呼び出し元プロセスの環境を使用する。
lpCurrentDirectory : [wstr] プロセスの現在のディレクトリへのフルパス。UNC パスも指定できる。このパラメータが NULL の場合、新しいプロセスは呼び出し元プロセスと同じ現在のドライブとディレクトリを持つ。(この機能は主に、アプリケーションを起動して初期のドライブと作業ディレクトリを指定する必要があるシェルのために提供されている。)
lpStartupInfo : [var] STARTUPINFO または STARTUPINFOEX 構造体へのポインタ。ユーザーは指定したウィンドウステーションとデスクトップの両方に完全なアクセス権を持っている必要がある。プロセスをインタラクティブにしたい場合は winsta0\default を指定する。lpDesktop メンバが NULL の場合、新しいプロセスは親プロセスのデスクトップとウィンドウステーションを継承する。このメンバが空文字列 "" の場合、新しいプロセスは「Process Connection to a Window Station」に記載されているルールに従ってウィンドウステーションに接続する。拡張属性を設定するには、STARTUPINFOEX 構造体を使用し、dwCreationFlags パラメータに EXTENDED_STARTUPINFO_PRESENT を指定する。STARTUPINFO または STARTUPINFOEX 内のハンドルは不要になったときに CloseHandle で閉じる必要がある。重要: 呼び出し元は STARTUPINFO 内の標準ハンドルフィールドが有効なハンドル値を含むことを保証する責任がある。これらのフィールドは、dwFlags メンバが STARTF_USESTDHANDLES を指定している場合でも、検証なしに子プロセスにそのままコピーされる。不正な値は子プロセスの不正動作やクラッシュを引き起こす可能性がある。不正なハンドルを検出するには Application Verifier 実行時検証ツールを使用する。
lpProcessInformation : [var] 新しいプロセスに関する識別情報を受け取る PROCESS_INFORMATION 構造体へのポインタ。

(プラグイン / モジュール : advapi32.dll)

解説

新しいプロセスとそのプライマリスレッドを作成する。新しいプロセスは、指定したトークンが表すユーザーのセキュリティコンテキストで動作する。(Unicode)

[戻り値]
関数が成功した場合、戻り値は 0 以外となる。関数が失敗した場合、戻り値は 0 となる。拡張エラー情報を取得するには
GetLastError を呼び出す。関数はプロセスの初期化が完了する前に復帰することに注意。必要な DLL
が見つからないか初期化に失敗した場合、プロセスは終了される。プロセスの終了ステータスを取得するには GetExitCodeProcess
を呼び出す。

[備考]
CreateProcessAsUser は、呼び出し元プロセスのプライマリトークンを TOKEN_DUPLICATE および
TOKEN_IMPERSONATE アクセス権で開けなければならない。既定では、CreateProcessAsUser
はユーザーから見えず入力を受け取れない、非インタラクティブなウィンドウステーション上の非表示デスクトップで新しいプロセスを作成する。新しいプロセスとのユーザー操作を可能にするには、STARTUPINFO
構造体の lpDesktop メンバで既定のインタラクティブなウィンドウステーションとデスクトップの名前
"winsta0\default" を指定する必要がある。さらに、CreateProcessAsUser
を呼び出す前に、既定のインタラクティブなウィンドウステーションと既定のデスクトップの両方の任意アクセス制御リスト (DACL)
を変更する必要がある。ウィンドウステーションとデスクトップの DACL は、hToken
パラメータで表されるユーザーまたはログオンセッションへのアクセスを許可する必要がある。CreateProcessAsUser
は指定したユーザーのプロファイルを HKEY_USERS レジストリキーに読み込まない。したがって、HKEY_CURRENT_USER
レジストリキー内の情報にアクセスするには、CreateProcessAsUser を呼び出す前に LoadUserProfile
関数でユーザーのプロファイル情報を HKEY_USERS に読み込む必要がある。新しいプロセスが終了した後は必ず
UnloadUserProfile を呼び出すこと。lpEnvironment パラメータが NULL
の場合、新しいプロセスは呼び出し元プロセスの環境を継承する。CreateProcessAsUser は hToken
が表すユーザー固有の環境変数を含むように環境ブロックを自動的に変更しない。たとえば、lpEnvironment が NULL
の場合、USERNAME と USERDOMAIN
変数は呼び出し元プロセスから継承される。新しいプロセスのために環境ブロックを準備し、lpEnvironment
で指定するのは呼び出し側の責任である。CreateProcessWithLogonW および
CreateProcessWithTokenW 関数は、呼び出し元がユーザーを認証してトークンを取得するために LogonUser
関数を呼び出す必要がない点を除き、CreateProcessAsUser と同様である。CreateProcessAsUser
は、呼び出し元または対象ユーザーのセキュリティコンテキストで指定したディレクトリと実行可能イメージにアクセスすることを可能にする。既定では、CreateProcessAsUser
は呼び出し元のセキュリティコンテキストでディレクトリと実行可能イメージにアクセスする。この場合、呼び出し元がディレクトリと実行可能イメージへのアクセスを持たないと関数は失敗する。対象ユーザーのセキュリティコンテキストを使用してディレクトリと実行可能イメージにアクセスするには、CreateProcessAsUser
を呼び出す前に ImpersonateLoggedOnUser 関数の呼び出しで hToken
を指定する。プロセスにはプロセス識別子が割り当てられる。識別子はプロセスが終了するまで有効である。プロセスの識別、または
OpenProcess
関数でプロセスへのハンドルを開くために指定できる。プロセスの初期スレッドにもスレッド識別子が割り当てられる。OpenThread
関数でスレッドへのハンドルを開くために指定できる。識別子はスレッドが終了するまで有効で、システム内でスレッドを一意に識別するのに使用できる。これらの識別子は
PROCESS_INFORMATION
構造体で返される。呼び出し元スレッドは、新しいプロセスが初期化を完了し入力保留なしでユーザー入力を待機する状態になるまで待つために
WaitForInputIdle 関数を使用できる。これは親プロセスと子プロセス間の同期に便利である。なぜなら
CreateProcessAsUser
は新しいプロセスが初期化を完了するのを待たずに復帰するからである。たとえば、作成元プロセスは新しいプロセスに関連付けられたウィンドウを見つけようとする前に
WaitForInputIdle を使用する。プロセスをシャットダウンする推奨方法は ExitProcess
関数を使用することである。なぜならこの関数はプロセスにアタッチされているすべての DLL
に終了の接近を通知するからである。プロセスをシャットダウンする他の手段はアタッチされた DLL に通知しない。スレッドが
ExitProcess を呼び出すと、プロセスの他のスレッドは(アタッチされた DLL
のスレッド終了コードを含む)追加コードを実行する機会なしに終了されることに注意。詳細は「Terminating a
Process」を参照のこと。既定では、bInheritHandles パラメータの値として TRUE
を渡すと、すべての継承可能なハンドルが新しいプロセスに継承される。これは、複数のスレッドから同時にプロセスを作成するが各プロセスに異なるハンドルを継承させたいアプリケーションでは問題となりうる。アプリケーションは、PROC_THREAD_ATTRIBUTE_HANDLE_LIST
パラメータ付きの UpdateProcThreadAttributeList
関数を使用して、特定のプロセスに継承させるハンドルのリストを提供できる。セキュリティに関する注意事項 lpApplicationName
パラメータは NULL にでき、その場合は実行可能名が lpCommandLine
内で最初の空白区切り文字列でなければならない。実行可能ファイルやパス名に空白が含まれると、関数が空白を解析する方法のために別の実行可能ファイルが実行されるリスクがある。次の例は危険である。なぜなら関数は
"MyApp.exe" の代わりに "Program.exe" が存在すればそれを実行しようとするからである。
(以下省略)

情報

プラグイン / モジュールadvapi32.dll
バージョン1.0
作成日2026/04/16
著作者IronHSP / CsWin32 bridge
URLhttps://github.com/inovia/IronHSP
備考Win32 API の advapi32.dll 関数群。CsWin32 + win32metadata から自動生成。
hsp3net 専用 (intptr / NSTRUCT / wstr を使用)。
タイプ拡張命令
グループWin32API
対応環境
  • Windows 版 HSP
hs ファイルhsphelp\win32_advapi32_gen2.hs