CreateProcessWithLogonW

https://msdn.microsoft.com/ja-jp/library/cc447468.aspx https://msdn.microsoft.com/ja-jp/library/cc429838.aspx https://msdn.microsoft.com/ja-jp/library/cc428987.aspx https://msdn.microsoft.com/ja-jp/library/cc429265.aspx https://msdn.microsoft.com/ja-jp/library/aa373491.aspx https://msdn.microsoft.com/ja-jp/library/ms686331.aspx https://msdn.microsoft.com/ja-jp/library/ms684873.aspx https://msdn.microsoft.com/ja-jp/library/cc428944.aspx https://msdn.microsoft.com/ja-jp/library/ms686331.aspx https://msdn.microsoft.com/ja-jp/library/aa374341.aspx https://msdn.microsoft.com/ja-jp/library/ms684873.aspx https://msdn.microsoft.com/ja-jp/library/cc429605.aspx https://msdn.microsoft.com/ja-jp/library/ms684873.aspx https://msdn.microsoft.com/ja-jp/library/cc429163.aspx https://msdn.microsoft.com/ja-jp/library/cc429605.aspx https://msdn.microsoft.com/ja-jp/library/aa373491.aspx https://msdn.microsoft.com/ja-jp/library/cc429265.aspx https://msdn.microsoft.com/ja-jp/library/cc429803.aspx https://msdn.microsoft.com/ja-jp/library/cc429838.aspx https://msdn.microsoft.com/ja-jp/library/aa374341.aspx https://msdn.microsoft.com/ja-jp/library/cc447468.aspx https://msdn.microsoft.com/ja-jp/library/ms684873.aspx https://msdn.microsoft.com/ja-jp/library/cc428987.aspx https://msdn.microsoft.com/ja-jp/library/ms686331.aspx

新しいプロセスとそのプライマリスレッドを作成します。新しいプロセスは、指定した認定証明( ユーザー、ドメイン、パスワード)のセキュリティコンテキストで、指定した実行可能ファイルを実行します。指定したユーザーのユーザープロファイルをロードすることもできます。

CreateProcessWithLogonW 関数は CreateProcessAsUser 関数と似ています。異なるのは、呼び出し側が 関数を使ってユーザーの認証とトークンの取得を行う必要がない点です。

BOOL CreateProcessWithLogonW(
  LPCWSTR lpUsername,            // ユーザーの名前
  LPCWSTR lpDomain,              // ユーザーのドメイン
  LPCWSTR lpPassword,            // ユーザーのパスワード
  DWORD dwLogonFlags,            // ログオン オプション
  LPCWSTR lpApplicationName,     // 実行可能モジュール名
  LPWSTR lpCommandLine,          // コマンドライン文字列
  DWORD dwCreationFlags,         // 作成フラグ
  LPVOID lpEnvironment,          // 新しい環境ブロック
  LPCWSTR lpCurrentDirectory,    // カレントディレクトリの名前
  LPSTARTUPINFOW lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);

パラメータ

lpUsername
ユーザーの名前を表す NULL で終わる文字列へのポインタを指定します。これは、ロゴオン先ユーザーアカウントの名前です。user@DNS_domain_name の形式を使う場合は、lpDomain パラメータに NULL を指定してください。

ユーザーアカウントには、ローカルコンピュータ上の Log On Locally アクセス権が必要です。このアクセス権は、ワークステーションとサーバー上ではすべてのユーザーに与えられますが、ドメインコントローラ上では管理者にしか与えられません。

lpDomain
NULL で終わる文字列へのポインタを指定します。この文字列は、lpUsername で指定するアカウントが登録されたアカウントデータベースがあるドメインまたはサーバーの名前を表します。
NULL を指定すると、ローカルアカウントデータベースを使ってアカウントが有効かどうかチェックされます。指定したアカウントがローカルアカウントデータベースで見つからなければ、その信頼されているドメインが、一致するアカウントが見つかるまでアカウントデータベースの検索を行います。このパラメータに NULL を指定する場合は、ユーザー名を UPN 形式で表す必要があります。
lpPassword
lpUsername で指定するアカウントのクリアテキストのパスワードを表す NULL で終わる文字列へのポインタを指定します。
dwLogonFlags
ログオン オプションを指定します。このパラメータは、次のいずれかの値となります。
意味
LOGON_WITH_PROFILEユーザーがログオンを終了した後にそのユーザーのプロファイルがロードされます。プロファイルをロードすると時間がかかることがあるため、このフラグは、ユーザーのプロファイル情報にアクセスする必要がある場合だけセットするようにします。
LOGON_NETCREDENTIALS_ONLYネットワーク上での認証を得たユーザーのみログオンします。

lpApplicationName
実行するモジュールを表す NULL で終わる文字列へのポインタを指定します。
この文字列は、実行するモジュールのフルパスとファイル名でも、モジュール名の一部でもかまいません。名前の一部を指定すると、指定を完全にするためにカレントドライブとカレントディレクトリが使われます。検索パスは使われません。

このパラメータには NULL を指定することもできます。その場合は、lpCommandLine に指定する文字列の最初のトークン( 空白類で区切る最初の文字列)がモジュール名でなければなりません。空白を含むロングファイル名を使う場合は、ファイル名の終わりと引数の始まりを明確にし、複数の解釈を避けるため、ファイル名を引用符で囲みます。たとえば、"c:\program files\sub dir\program name" のような文字列は、何通りかの解釈方法があります。実際、次の順序で、次の 4 通りの解釈が行われます。

c:\program.exe files\sub dir\program name
c:\program files\sub.exe dir\program name
c:\program files\sub dir\program.exe name
c:\program files\sub dir\program name.exe

実行するモジュールとして Win32 アプリケーションを指定できます。ローカルコンピュータ上で対応するサブシステムが利用できるときは、MS-DOS、OS/2 など、Win32 以外のモジュールも指定できます。実行するモジュールとして 16 ビットアプリケーションを指定する場合は、lpApplicationName に NULL を指定し、lpCommandLine が指す文字列で実行可能モジュールの名前と引数を指定します。16 ビットアプリケーションは、VDM プロセスまたは WOW プロセスとして実行されるアプリケーションです。

lpCommandLine
実行するコマンドラインを表す NULL で終わる文字列へのポインタを指定します。コマンドラインには、終端に NULL が付加され、必要に応じて文字列が切り取られ、実際にどのファイルが使われたかが示されます。

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

lpApplicationName lpCommandLine の両方に NULL 以外の文字列を指定すると、*lpApplicationName が指す文字列が実行するモジュールとして扱われ、*lpCommandLine が指す文字列がコマンドラインとして扱われます。新しいプロセスは全てのコマンドラインを検索するために GetCommandLine を使うことができます。C ランタイムプロセスは、argc 引数と argv 引数を使うことができます。慣例では、コマンドラインの最初のトークンでモジュール名をもう一度指定します。

lpApplicationName に NULL を指定すると、コマンドラインの最初のトークン(空白類で区切る最初の文字列)がモジュール名として扱われます。空白を含むロングファイル名を使う場合は、ファイル名の終わりと引数の始まりを示すために、ファイル名を引用符で囲んでください(lpApplicationName の説明を参照してください)。ファイル名に拡張子が含まれていない場合は、.exe が付加されます。ファイル名の最後がピリオド(.)で、拡張子を付けていない場合、またはファイル名にパスが含まれている場合は、.exe が付加されません。ファイル名にディレクトリパスが含まれていない場合は、実行可能ファイルが次の順序で検索されます。

  1. アプリケーションのロード元のディレクトリ

  2. カレントディレクトリ

  3. 32 ビット Windows システムディレクトリ。このディレクトリのパスは、GetSystemDirectory 関数を使って取得します。このディレクトリの名前は System32 です。

  4. 16 ビット Windows システムディレクトリ。このディレクトリのパスを取得するための Win32 関数はありませんが、ディレクトリでの検索は行われます。このディレクトリの名前は System です。

  5. Windows ディレクトリ。このディレクトリのパスは、 関数を使って取得します。

  6. PATH 環境変数に含まれている各ディレクトリ
dwCreationFlags
プロセスの作成方法を指定するフラグです。既定値では、CREATE_DEFAULT_ERROR_MODE フラグ、CREATE_NEW_CONSOLE フラグ、CREATE_NEW_PROCESS_GROUP フラグがオンです。次の表に従って、追加のフラグをセットできます。
フラグ意味
CREATE_DEFAULT_
ERROR_MODE
呼び出しプロセスのエラーモードを新しいプロセスに継承させません。代わりに、新しいプロセスに現在の既定エラーモードを適用します。既定エラーモードは、 関数で設定します。

このフラグは既定値でオンです。

CREATE_NEW_
CONSOLE
新しいプロセスに親のコンソールを継承させずに、新しいコンソールを与えます。DETACHED_PROCESS フラグを同時にセットすることはできません。

このフラグは既定値でオンです。

CREATE_NEW_
PROCESS_GROUP
新しいプロセスをルートプロセスにして新しいプロセスグループを作成します。プロセスグループには、このルートプロセスの子孫となるすべてのプロセスが含まれます。新しいプロセスグループのプロセス識別子は、lpProcessInformation パラメータが指す構造体に格納されるプロセス識別子と同じです。プロセスグループは、 関数によって、コンソールプロセスのグループへの CTRL+C 信号または CTRL+BREAK 信号の送信を有効にするときに使います。

このフラグは既定値でオンです。

CREATE_SEPARATE_
WOW_VDM
16 ビット Windows アプリケーションを起動するときだけ有効です。このフラグをセットすると、新しいプロセスがプライベートな仮想 DOS マシン(VDM)で実行されます。このフラグをセットしない場合( 規定値)、16 ビット Windows アプリケーションはすべて単一の共有 VDM で実行されます。アプリケーションを別の VDM で実行する利点は、クラッシュしてもその VDM だけが終了し、別の VDM で実行されている他のプログラムは正常に機能し続けることです。また、別の VDM で実行されている 16 ビット Windows アプリケーションは専用の入力待ち行列を持ちます。つまり、そのアプリケーションが少しの間応答を停止しても、別の VDM で実行されているアプリケーションは入力を受け付けます。
CREATE_SUSPENDED新しいプロセスのプライマリスレッドを作成し、その実行を中断します。このスレッドは、ResumeThread 関数を呼び出すまで実行されません。
CREATE_UNICODE_
ENVIRONMENT
lpEnvironment パラメータの形式を示します。lpEnvironment が指す環境ブロックで Unicode 文字を使う場合は、このフラグをセットします。ANSI 文字を使う場合は、このフラグをクリアします。

dwCreationFlags パラメータでは、新しいプロセスの優先順位クラスも指定します。優先順位クラスによって、プロセスに属するスレッドのスケジューリング優先順位が決まります。優先順位クラスを制御する次のフラグを何もセットしないと、新しいプロセスの優先順位クラスは既定値で NORMAL_PRIORITY_CLASS になります。ただし、作成側プロセスの優先順位クラスが IDLE_PRIORITY_CLASS または BELOW_NORMAL_PRIORITY_CLASS のときは、呼び出し側プロセスの既定優先順位クラスが子プロセスに適用されます。次のフラグのいずれかをセットすることができます。

フラグ意味
ABOVE_NORMAL_PRIORITY_CLASSWindows 2000:優先順位が NORMAL_PRIORITY_CLASS より高く、HIGH_PRIORITY_CLASS より低いプロセスを作成します。
BELOW_NORMAL_
PRIORITY_CLASS
Windows 2000:優先順位が IDLE_PRIORITY_CLASS より高く、NORMAL_PRIORITY_CLASS より低いプロセスを作成します。
HIGH_PRIORITY_
CLASS
ただちに実行しなければならないタイムクリティカルなタスクを実行するプロセスを作成します。このクラスに属するプロセスのスレッドは、NORMAL_PRIORITY_CLASS クラスまたは IDLE_PRIORITY_CLASS クラスのスレッドに優先して実行されます。例として[アプリケーションの切り替え]があります。このツールは、ユーザーから呼び出しがあったときは、オペレーティングシステムの負荷にかかわらず即座に応答しなければなりません。この優先順位クラスは慎重に扱ってください。このクラスに属する、CPU への負荷が大きいアプリケーションは、利用可能なほとんどすべての CPU サイクルを消費します。
IDLE_PRIORITY_
CLASS
このクラスに属するプロセスのスレッドは、システムがアイドルのときだけ実行されます。より高い優先順位クラスで実行中のプロセスがあるときは、そのプロセスのスレッドが先に実行されます。例としてスクリーンセーバーがあります。この優先順位クラスは、子プロセスに継承されます。
NORMAL_PRIORITY_
CLASS
特別なスケジューリングを必要としない一般的なプロセスを作成します。
REALTIME_
PRIORITY_CLASS
優先順位が最も高いリアルタイムプロセスを作成します。この優先順位クラスに属するプロセスのスレッドは、重要なタスクを実行するオペレーティングシステムプロセスを含め、すべてのプロセスのスレッドに優先して実行されます。たとえば、このクラスのプロセスの実行時間が少しでも長くなると、ディスクキャッシュがフラッシュされなくなったり、マウスが応答しなくなったりします。

lpEnvironment
新しいプロセスの環境ブロックへのポインタを指定します。NULL を指定すると、呼び出し側プロセスの環境が使われます。

環境ブロックは、NULL で終わる文字列の NULL で終わるブロックです。各文字列は次の形式になります。

name=value

等号は区切り文字として使われるため、環境変数名に等号を使わないでください。

このパラメータに NULL を指定せず、環境ブロックを指定すると、そのままでは、システムドライブのカレントディレクトリの情報が新しいプロセスに伝播されません。詳しい説明と対処方法は、下の解説を参照してください。

環境ブロックは、Unicode 文字または ANSI 文字で記述できます。lpEnvironment が指す環境ブロックを Unicode 文字で記述した場合は、dwCreationFlags パラメータの CREATE_UNICODE_ENVIRONMENT フラグをセットしてください。環境ブロックを ANSI 文字で記述した場合は、このフラグをセットしないようにします。

ANSI で記述する環境ブロックは、2 バイトの 0 で終わります。1 つは最後の文字列の終わり、もう 1 つのバイトはブロックの終わりを示します。Unicode で記述する環境ブロックは 4 バイトの 0 で終わります。最初の 2 バイトは文字列の終わり、残りの 2 バイトはブロックの終わりを示します。

特定のユーザーの環境ブロックを取得するには、 関数を使います。

lpCurrentDirectory
新しいプロセスのカレントドライブとカレントディレクトリを表す NULL で終わる文字列へのポインタを指定します。この文字列は、ドライブ文字を含むフルパスとファイル名でなければなりません。NULL を指定すると、新しいプロセスのカレントドライブは、そのプロセスを作成するシステムサービスと同じになります( このパラメータは主にシェルで使います。シェルは、アプリケーションを起動し、その初期のドライブと作業ディレクトリを指定する必要があります)。
lpStartupInfo
新しいプロセスのメインウィンドウの表示方法が入った 構造体へのポインタを指定します。
lpProcessInformation
新しいプロセスの識別情報を受け取る 構造体へのポインタを指定します。

戻り値

関数が成功すると、0 以外の値が返ります。
関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、 関数を使います。

解説

既定値では、デスクトップが可視でなく、ユーザー入力を受け付けることができない非対話型のウィンドウステーション上に新しいプロセスが作成されます。新しいプロセスでユーザーとの対話を可能にするには、 構造体の lpDesktop メンバを既定対話型ウィンドウステーションと既定デスクトップの名前である "winsta0\default" に設定しておく必要があります。さらに、この関数を呼び出す前に、既定対話型ウィンドウステーションと既定デスクトップの両方の随意アクセス制御リスト(DACL)を変更しなければなりません。それぞれの DACL で、lpUsername パラメータで指定するユーザーへのアクセス権を認めておきます。

指定したユーザーのプロファイルは HKEY_USERS レジストリキーにロードされません。つまり、HKEY_CURRENT_USER レジストリキーの情報にアクセスしても、通常の対話型ログオンと一貫する結果が得られないことがあります。そのため、この関数を呼び出す前に 関数を使って、ユーザーのレジストリハイブを HKEY_USERS にロードしておく必要があります。

lpEnvironment に NULL を指定すると、呼び出し側プロセスの環境が新しいプロセスに継承されます。ただし、そのままでは、ユーザー固有の環境変数が環境ブロックに追加されません。たとえば、lpEnvironment に NULL を指定すると、呼び出し側プロセスから USERNAME 変数と USERDOMAIN 変数が継承されます。新しいプロセスの環境ブロックを用意し、lpEnvironment で指定する必要があります。
新しいプロセスと新しいスレッドのハンドルは、フルアクセス権(PROCESS_ALL_ACCESS と THREAD_ALL_ACCESS)で作成されます。どちらのハンドルも、セキュリティ記述子が与えられていなければ、そのタイプのオブジェクトハンドルを必要とするどの関数でも使うことができます。セキュリティ記述子が与えられているときは、そのハンドルを使うたびにアクセスチェックが行われます。アクセスチェックでアクセスが拒否されると、要求側のプロセスがそのハンドルを使ってプロセスまたはスレッドにアクセスすることはできません。

lpProcessAttributes パラメータに NULL を指定すると、ユーザーの既定のセキュリティ記述子が使われます。このセキュリティ記述子が呼び出し側のアクセスを認めていないことがあります。その場合は、プロセスを一度実行すると、そのプロセスを二度と開くことができません。PROCESS_INFORMATION 構造体が受け取るハンドルは有効で、引き続きすべてのアクセス権を持ちます。このことは、スレッド属性にも当てはまります。
構造体で受け取ったハンドルは、不要になったら 関数で閉じてください。

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

lpApplicationName または lpCommandLine にアプリケーションの名前を指定するとき、ファイル名の拡張子は省略できます。ただし、拡張子が .com の MS-DOS アプリケーションまたは Windows アプリケーションを指定するときは、拡張子 .com を必ず付けてください。

呼び出し側スレッドは、WaitForInputIdle 関数を使って、新しいプロセスがその初期化を完了し、処理待ちの入力データがない状態でユーザー入力を待機するようになるまで待つことができます。CreateProcessWithLogonW 関数は新しいプロセスがその初期化を完了するのを待たずに制御を戻すため、親プロセスと子プロセスを同期化したい場合はこの方法を利用できます。たとえば、新しいプロセスに関連付けられたウィンドウを見つけようとする場合は、その前に WaitForInputIdle 関数を呼び出します。
プロセスをシャットダウンするときは、できるだけ ExitProcess 関数を使ってください。そうすれば、プロセスが終了しようとしていることがアタッチされているすべてのダイナミックリンクライブラリ(DLL)に通知されます。他の方法では、アタッチされている DLL への通知は行われません。スレッドが ExitProcess 関数を呼び出すと、同じプロセスの他のスレッドはいっさいのコード( アタッチされている DLL のスレッド終了コードを含む)を実行する機会を与えられずに終了します。

ExitProcess 関数、ExitThread 関数、CreateThread 関数、CreateRemoteThread 関数、および実行を開始しようとしているプロセス(CreateProcessWithLogonW 関数の呼び出しによって)は、1 つの工程の中で互いにシリアル化されます。これらの 2 つ以上のイベントが同時に発生することはできません。次の制限が適用されます。

  • プロセス開始ルーチンと DLL 初期化ルーチンの実行中、新しいスレッドを作成できますが、プロセスの DLL 初期化が完了するまでスレッドの実行を開始することはできません。

  • DLL 初期化ルーチンまたはデタッチルーチン中は、プロセス内に同時に複数のスレッドが存在できません。

  • ExitProcess 関数は、DLL 初期化ルーチンまたはデタッチルーチンを実行中のスレッドがなくなるまで、制御を戻しません。

対応情報

Windows NT/2000:Windows 2000
Windows 95/98:対応していません
Windows CE:対応していません
ヘッダー:winbase.h 内で宣言
インポートライブラリ:advapi32.lib を使用

参照

、、、CreateProcessAsUserCreateRemoteThreadCreateThreadExitProcessExitThread、、GetCommandLineGetEnvironmentStringsGetExitCodeProcess、、、LoadModule、、、OpenProcessOpenThread、、ResumeThread、、、WaitForInputIdle

表示: