[INFO] COM サーバーのアクティブ化と NT のウィンドウ ステーション

文書翻訳 文書翻訳
文書番号: 169321 - 対象製品
この記事は、以前は次の ID で公開されていました: JP169321
すべて展開する | すべて折りたたむ

目次

概要

クライアントが登録済みクラスのクラス オブジェクトを要求すると、COM は既存のクラス オブジェクトを返すか、または要求されたオブジェクトを含むものとして登録されているプロセスを起動します。要求クライアントのクラス オブジェクトの参照を取得する処理は、"アクティブ化" と呼ばれます (プロセスの作成または "起動" が行われているかどうかには関係なく、このように呼びます)。

特定の条件下では、既存のクラス オブジェクトが実行中で、マルチユースとして登録されている場合であっても、COM が新しいサーバー プロセスを起動することがあります。さらに、COM が新しいプロセスを作成すると、新規のセキュリティ環境 ("ウィンドウ ステーション" と呼ばれます) で起動される場合があります。この場合、対話型ウィンドウ ステーションなどの既存のものを共有しません (ウィンドウ ステーションの詳細については、Win32 SDK のドキュメントで該当する語句を検索してください)。

アクティブ化要求の際に COM が新しいプロセスやウィンドウ ステーションを作成するアルゴリズムを理解することは、複数の理由から重要です。第 1 に、COM はセキュリティ上の理由から、マルチユースのクラス オブジェクトのプロセス インスタンスを複数作成する場合があります。第 2 に、"シングルユース" のサーバーは、常に独立したプロセスとして起動されますが、独立したウィンドウ ステーションで起動される場合もあればそうでない場合もあります。ある特殊なケースでは、この違いがアプリケーションのコードに現れることがあります。たとえば、2 つの COM サーバーが、ウィンドウ メッセージやセキュリティで保護された通信機能 (COM または RPC など) を経由して通信しようとする場合などです。第 3 に、Windows NT で同時に作成できるウィンドウ ステーションの数には制限があるため、COM サーバーが新しいウィンドウ ステーションをいつ取得するのかを知ることは重要です。

この資料では、さまざまなアクティブ化シナリオを検討し、新しいプロセスやウィンドウ ステーションが作成されるタイミングについて説明しています。

詳細

COM が新しいサーバー プロセスを作成するタイミング、または新しいウィンドウ ステーションを新しいサーバー プロセスに割り当てるタイミングは、以下の複数の要因によって決まります。
  1. COM クラスの起動に使用するように設定されたセキュリティ ID。クラスの ID は、DCOMCNFG ツールを使用して設定でき、そのクラスの AppID キーの下にある名前付きの値 RunAs で指定されます。
  2. クラス オブジェクトによる登録がシングルユースかマルチユースか。
  3. クライアント プロセスのセキュリティ ID (SID) (これは Windows NT 環境で特定のユーザー アカウント、セキュリティ ID、プリンシパルを表す数値です)。
  4. クライアント プロセスのログオン ID (LUID)。(Windows NT を実行しているコンピュータへの一意なログオンそれぞれに対して新しいログオン ID が生成されます。このログオンには、ユーザーが NT のログオン画面でユーザー名とパスワードを入力する場合と、Win32 API の LogonUser を呼び出す場合とがあります)
  5. ローカルのアクティブ化かリモートのアクティブ化か。
  6. クライアントのウィンドウ ステーション。

マルチユース クラス

マルチユース クラスは、(CoRegisterClassObject() API を通じて) REGCLS_MULTIPLEUSE フラグを指定して COM に登録されたクラスです。このようなクラスの場合、COM は通常、すべてのクライアントのアクティブ化要求に対してサーバー プロセスの同一のインスタンスを使用します。ただし、起動したユーザーのセキュリティで実行するように構成されたクラスやその他のいくつかのケースでは、サービスのアクティブ化要求に対して、COM はサーバー プロセスの新しいインスタンスを起動します。こうしてサーバー プロセスの新しいインスタンスが起動されると、サーバー プロセスで新しいウィンドウ ステーションを取得することが同様に可能です。以下では、さまざまなシナリオを検討しますが、その前にまず、要求されたクラス オブジェクトが "マルチユース" クラスとして既に登録されている場合に、COM がそのクラス オブジェクトを含む新しいプロセスを起動する理由について説明しておきます。

第 1 に、COM クラス (より正確には、COM クラスに対応する AppID) が "起動したユーザー" として実行されるようにシステムに登録されている場合、システム管理者は、そのクラスに関して特定のセキュリティ ポリシーを設定しています。そのポリシーとは、アクティベータが、アクティブ化を行うコードと同じセキュリティ コンテキストで実行しているプロセス内のクラス オブジェクトを受け取る必要があるというものです。

このセキュリティ ポリシーは、すべてのアクティブ化要求に対してクラスのファクトリ オブジェクトを 1 つだけ持つという (REGCLS_MULTIPLEUSE によって示される) サーバー定義の動作と競合する可能性があります。COM では、アプリケーション動作よりもセキュリティ ポリシーが優先されます。その結果、"起動したユーザー" として実行するように登録されたマルチユース サーバーは、マルチユースの標準規則に従って動作しないことになります。アクティブ化を行う各セキュリティ プリンシパルに対して、新しいプロセスが起動されます。

第 2 に、ある CLSID に指定されたセキュリティ コンテキストとは異なるセキュリティ コンテキストで実行している COM が起動したものではないプロセスがその CLSID を登録すると、登録は失敗します (この場合は、CoRegisterClassObject がエラー コード CO_E_WRONG_SERVER_IDENTITY を返します)。アクティブ化要求が後で到着した場合には、COM が CLSID または AppID に指定されたセキュリティ コンテキストを使用して新しいプロセスを起動します。使用するクラス オブジェクトとその実行方法を COM が判断する際に、CoRegisterClassObject() を呼び出すコード (セキュリティで保護されていない操作) は信頼できません。信頼できるのはレジストリ設定だけです (レジストリはセキュリティで保護されたデータベースです)。この動作により、コンピュータ全体に及ぶ、許可されていないユーザーによるクラス オブジェクトの 不正な操作 を防止します。

以上を考慮して、マルチユースのサーバーが COM によって起動されたときに、新しいプロセスとウィンドウ ステーションが作成されるタイミングの問題に戻ります。マルチユースのクラスの場合は、クライアントの LUID は一切関係ないことに注意してください。
  1. "対話ユーザー" セキュリティ ID。マルチユース COM クラスの AppID が "対話ユーザー" として実行されるように構成されている場合、COM は最初のサーバー プロセスとそのクラス オブジェクトを使用して、それ以後のすべてのアクティブ化要求を処理します。このサーバー インスタンスは、対話型ウィンドウ ステーションが存在すれば、それを持つことになります (ローカルにログオンしているユーザーがいない場合は、すべてのアクティブ化要求が失敗します)。上記のように、COM によって起動されたものではなく、対話型ウィンドウ ステーションで実行されていないプロセスが CLSID を登録すると、その登録は失敗します。後でアクティブ化要求が到着すると、対話ユーザーのセキュリティ コンテキストを使用して新しいプロセスが起動されます。この動作により、クラス オブジェクトの 不正な操作 を防止します。COM によって起動された別のサーバー プロセスは存在しないため、新しいウィンドウ ステーションに関する問題は、 ここでは該当しません 。クライアントの SID、その LUID またはそれがローカルかリモートかは、この場合関係ありません。
  2. "このユーザー" セキュリティ ID。同様に、マルチユース COM クラスの AppID が "このユーザー" (定義済みセキュリティ ID) として実行するように構成されている場合、COM は最初のサーバー プロセスとそのクラス オブジェクトを使用して、それ以後のすべてのアクティブ化要求を処理します。この最初のサーバー インスタンスは、最初のプロセス作成の一部として作成される独自のウィンドウ ステーションを持つことになります。COM によって起動された別のサーバー プロセスは存在しないため、別のウィンドウ ステーションに関する問題は、 ここでは該当しません 。クライアントの SID、その LUID またはそれがローカルかリモートかは、この場合関係ありません。"このユーザー" として実行するように構成されたクラスまたは AppID の最初のインスタンスを起動すると、同じユーザーが対話型 ウィンドウ ステーション に現在ログオンしている場合であっても、新しいウィンドウ ステーションが作成されることに注意してください。"このユーザー" として実行するように構成されたサーバーを起動する際、COM が対話型 ウィンドウ ステーション を使用することはありません。使用すると、現在のログオン ユーザーの ID という無関係な問題によって、クラスの動作が変わる結果になるためです。上記のように、COM によって起動されておらず、"このユーザー" で指定されるアカウントで実行されていないプロセスが CLSID を登録しようとすると、その登録は失敗し、後でアクティブ化要求が到着した場合には、新しいプロセスが "このユーザー" アカウントで起動されます。この動作により、クラス オブジェクトの 不正な操作 を防止します。一方、ある CLSID や APPID に対して登録されるプロセスが、"このユーザー" として実行するように構成され、COM 以外の何らかのエージェントによって該当するユーザー アカウントで作成された場合 (たとえば、対話ユーザーが "このユーザー" と同じユーザーの場合は対話ユーザーによって実行され、また "このユーザー" と同じセキュリティ コンテキストで実行しているサービスによって、CreateProcess() を経由して起動される場合もあります)、次にそのプロセスが REGCLS_MULTIPLEUSE クラス オブジェクトを登録すると、COM は既存の実行中のクラス オブジェクトを使用して、それ以後に任意のクライアントから受け取るアクティブ化要求を処理します。
  3. "起動したユーザー" セキュリティ ID。この場合、クラスの AppID は、"起動したユーザー" の ID (これは "アクティベータとしてアクティブ化" クラスとしても呼ばれます) で起動するように設定されます。a. ローカル クライアント。最初に、ローカル コンピュータの場合を考えます。ここでは、2 つの規則があります。1. それぞれの異なるアクティブ化クライアントの SID に対して、同じウィンドウ ステーションでも、COM はサーバー プロセスの新しいインスタンスを起動します。2. SID が一致する場合 (同じユーザーが 1 つの NT コンピュータに複数回ログオンしている場合など) でも、それぞれの異なるローカル ウィンドウ ステーションに対して、COM はサーバー プロセスの新しいインスタンスを起動します。言い換えれば、起動したユーザー ID のマルチユース サーバーは、複数のウィンドウ ステーションにわたって共有されることはありません。同じ SID と同じウィンドウ ステーションを持つすべてのクライアントは、同じウィンドウ ステーション内で単一のサーバー プロセスを共有します。サーバーはクライアントのウィンドウ ステーションを共有するため、新しいウィンドウ ステーションは作成されません。たとえば、a_domain\a_user として対話型のログオンをしているとします。クライアントの複数のインスタンスを実行すると、それらのすべてが (対話型ウィンドウ ステーションを持っている) サーバーの同じインスタンスに接続します。ここで、サービスであるクライアントがあり、a_domain\a_user で起動するように設定されているとします。このサービスは COM サーバーの新しいインスタンスを起動します。これは、サービスのプロセスが対話型ウィンドウ ステーションとは別のウィンドウ ステーションを持っているため、COM がサーバーの新しいインスタンスを起動するために起こります。サービス (クライアント) の ID が、実行中のサーバー プロセスの ID (a_domain\a_user) と同一である場合も同じです。ただし、COM サーバー プロセスに対して新しいウィンドウ ステーションは作成されないことに注意してください。サーバーは引き続きサービスのウィンドウ ステーションを継承します。サービスが、LocalSystem で開始されるように、およびデスクトップと対話 (コントロール パネルの [サービス] の [デスクトップとの対話をサービスに許可] チェック ボックスを参照) するように設定されている場合、そのサービスは対話型ウィンドウ ステーションまたは winsta0 で実行されます。この場合も COM は対話型ウィンドウ ステーションでサーバーの新しいインスタンスを起動します (この場合のクライアントの SID は LocalSystem であり、サーバーの SID の a_domain\a_user と異なります)。b. リモート クライアント。リモートのアクティブ化の場合、クライアントがリモートであるため、上記のローカルの場合とは異なり COM はクライアントのウィンドウ ステーションを無視します。ここでの規則は、新しい各クライアントの SID に対して、サーバー プロセスの新しいインスタンスが起動され、それぞれの新しいサーバー プロセスが新しいウィンドウ ステーションを取得するというものです。同じ SID を持つリモート クライアントによる以後のアクティブ化要求では、既存の登録済みクラス オブジェクトの他、そのプロセスとウィンドウ ステーションが再利用されます。たとえば、a_domain\a_user として 10 台の異なるコンピュータにログオンしているとします。これらすべてのコンピュータのクライアントが、サーバー コンピュータにあるサーバーの同一のインスタンスに接続します。a_domain\b_user コンピュータのクライアントに対しては、新しいサーバー インスタンスと新しいウィンドウ ステーションが起動されます。要求される CLSID に対して登録されている COM サーバーを起動したローカル ユーザーと同じ SID を持つリモートの呼び出し元は、既存のクラス オブジェクトを再利用します。ただし、この場合は、COM サーバーが開始される順序が重要です。サーバーがローカル クライアントによって最初に起動された場合は、同じ SID を持つリモート クライアントはこのサーバーに接続します。これに対して、サーバーがリモート クライアントによって最初に起動された場合は、同じ SID を持つローカル クライアントはサーバーの新しいインスタンスを起動します。この場合は、前述のウィンドウ ステーションの規則に戻ります。ローカル クライアントの場合、クライアントとサーバーのウィンドウ ステーションは一致している必要があります。リモート クライアントの場合、クライアントのウィンドウ ステーションは無視されます。たとえば、ローカル クライアントの a_domain\a_user が最初にサーバーを起動した場合は、リモート クライアントの a_domain\a_user はサーバーに接続します。反対に、リモート クライアントの a_domain\a_user が最初にサーバーを起動した場合、ローカル クライアントの a_domain\a_user は、新しいサーバー インスタンスと新しいウィンドウ ステーションを起動します。この場合、クライアントの LUID は関係ありません。
  4. サービスベースの COM サーバー。サービスを起動できるのは 1 回だけであるため、Win32 サービスにパッケージされる COM クラスと AppID は、実用上の必要性からマルチユース サーバーとなります。この場合、最初のアクティブ化要求で、新しいプロセスが独自のウィンドウ ステーションで起動されます。これには 2 つの例外があります。a. サービスが LocalSystem アカウントで起動するように設定されている場合は、システムの事前に定義されたウィンドウ ステーションが継承されます。b. サービスが LocalSystem アカウントで起動するように設定され、デスクトップと対話できる場合は、対話型ウィンドウ ステーションまたは winsta0 が継承されます。以後のすべてのアクティブ化要求は、ローカルかリモートかによらず、そのサービスのクラス オブジェクトによって処理されます。上記のように、COM によって起動されておらず、指定されたサービスとして実行されていないプロセスが CLSID を登録すると、その登録は失敗し、後でアクティブ化要求が到着した場合には、登録されているサービスが起動されます。この動作により、クラス オブジェクトの 不正な操作 を防止します。

シングルユース クラス

注 : シングルユース クラスはできるだけ避けてください。シングルユースの登録はレガシ設定であり、古い COM アプリケーションのサポートや、COM 対応でないレガシ アプリケーションの COM への移植を容易にすることを意図したものです。新しいクラスは、マルチユース クラス オブジェクトの登録をサポートするように設計することを強く推奨します。これは、ID が "このユーザー" であるサーバーの場合は特にそうです。この条件では、シングルユース クラスがマルチユース クラスと正反対の効果をもたらします。以下に解説するように、アクティブ化のたびに新しいサーバー プロセスと新しいウィンドウ ステーションが作成され、これが原因で Windows NT でリソースの問題が発生する可能性があります。

シングルユース クラスは、(CoRegisterClassObject() API を通じて) REGCLS_SINGLEUSE フラグを指定して COM に登録されたクラスです。そのようなクラスに対しては、COM は常に、任意のクライアント (ローカルでもリモートでも) からの各アクティブ化要求に対して、そのクラスのサーバー プロセスの新しいインスタンスを起動します。 この資料の目的から、サーバーが新しいウィンドウ ステーションを取得するのはいつかという点について、以下で解説します。
  1. "対話ユーザー" セキュリティ ID。シングルユース クラスが、AppID を経由して "対話ユーザー" ID で起動するように設定されている場合を取り上げます。この場合、サーバー プロセスの新しい各インスタンスは常に、対話型ウィンドウ ステーションが存在すれば、それを持つことになります (ローカルにログオンしているユーザーがいない場合は、すべてのアクティブ化要求が失敗します)。COM によって新しいウィンドウ ステーションが作成されることはありません。
  2. "このユーザー" セキュリティ ID。次に、シングルユース COM クラスの AppID が、"このユーザー" ID で実行するように設定されている場合を検討します。この場合、規則は非常に単純です。新しいクライアントのアクティブ化のたびに、新しいウィンドウ ステーションで新しいプロセスが起動されます。これは、"このユーザー" として指定されたユーザーが、アクティブ化要求の際に対話型ウィンドウ ステーションにログオンしているかどうかに関係なく成立します。
  3. "起動したユーザー" セキュリティ ID。a. ローカル クライアント。ローカル コンピュータのアクティブ化シナリオでは、サーバー プロセスは常にクライアントのウィンドウ ステーションを取得します。新しいウィンドウ ステーションが作成されることはありません。たとえば、a_domain\a_user として対話型ログオンをしており、クライアント プログラムの複数のインスタンスを実行するとします。その結果、作成されるサーバーの新しい各インスタンスは、対話型ウィンドウ ステーションを取得することになります。次に、クライアントがローカル システム アカウントで実行しているサービスであると仮定します。この場合 COM サーバーは、サービス プロセスのウィンドウ ステーションを共有します。b. リモート クライアント。リモートのアクティブ化の場合、クライアントがリモートであるため、COM はクライアントのウィンドウ ステーションを無視します。他の場合と同様に、サーバーの新しいインスタンス プロセスが、リモートの各アクティブ化に対して起動されることになります。その規則は次のとおりです。1. 新しい各リモート クライアントの SID に対して、サーバー プロセスのために新しいウィンドウ ステーションが作成されます。2. 新しい各リモート クライアントの LUID に対して、サーバー プロセスのために新しいウィンドウ ステーションが作成されます。3. 同じ SID と LUID の対を持つすべてのリモート クライアントは、同じウィンドウ ステーションを共有するサーバーを作成します。たとえば、a_domain\a_user としてリモート クライアント コンピュータにログオンしているとします。このクライアントは、新しいウィンドウ ステーションを取得するリモート サーバーを起動します。ここで、a_domain\a_user がクライアント アプリケーションの第 2 のインスタンスを同じクライアント コンピュータから起動し、さらにリモート コンピュータ上でサーバーの新しいコピーを起動した場合、このサーバーは元のサーバーのウィンドウ ステーションを共有することになります。ここで、別のコンピュータに a_domain\a_user として再度ログオンし、そこでクライアントを実行したとします。対応するサーバー インスタンスは、新しいウィンドウ ステーションを持つことになります。これは、クライアントの SID が同じであっても、第 2 のクライアントは異なる LUID を持つために、そのサーバー プロセスは新しいウィンドウ ステーションを持つことを示しています。
  4. サービスベースの COM サーバー。シングルユースのクラスは、Windows NT サービスとして実装しないでください。Windows NT サービス プロセスのインスタンスは複数実行できないため、これを行っても意味がありません。

各シナリオをまとめた表

---------------------------------------------------------------------------
       |                      マルチ ユース サーバー
       |             (クラス ファクトリが再利用を要求)
       |                       アクティブ化モード
       |-------------------------------------------------------------------
       |   対話ユーザー    | "このユーザー"    |"起動したユーザー" | Win32
Cleint |                   |  として           | として            | サービス
Local  | 最初のアクティブ  | 最初のアクティブ  | 最初の要求時にク  | 最初のアクティブ
       | 化要求時に対話型  | 化要求時に新しい  | ライアント ウィン | 化要求でサービス
       | ウィンドウ ステ   | ウィンドウ ステー | ドウ ステーション | 開始 (サービスの
       | ーションでプロセ  | ションでプロセス  | でプロセス起動。  | 構成によって新し
       | ス起動。          | 起動。            | 以後の同じ SID/   | いウィンドウ ステ
       | 以後の要求は既存  | 以後の要求は既存  | ウィンドウ ステ   | ーションかシステ
       | のクラスオブジェ  | のクラス オブジェ | ーションからの要  | ム/対話型ウィンド 
       | クトを取得。      | クトを取得。      | 求は既存のクラス  | ウステーション)。
       | ローカルにログオ  |                   | オブジェクトを取  | 以後の要求は既存
       | ンしたユーザーが  |                   | 得。同じ SID でも | のクラス オブジ
       | なければアクティ  |                   | ウィンドウ ステー | ェクトを取得。
       | ブ化は失敗。      |                   | ションをまたぐ    | 
       |                   |                   | クラス オブジェク | 
       |                   |                   | トの共有はなし。  | 
-------|                   |                   |-------------------| 
Remote |                   |                   | SID による最初の  | 
       |                   |                   | アクティブ化要求  | 
       |                   |                   | 時に新しいウィン  |
       |                   |                   | ドウ ステーション |
       |                   |                   | でプロセス起動。  |
       |                   |                   | 同じ SID による以 |
       |                   |                   | 後のリモート要求  |
       |                   |                   | は既存のクラス    |
       |                   |                   | オブジェクトを取  |
       |                   |                   | 得。ローカル ユー |
       |                   |                   | ザーによって起動  |
       |                   |                   | されるクラスは同  |
       |                   |                   | じ SID のリモート |
       |                   |                   | 呼び出し元に共有  |
       |                   |                   | される。          |
---------------------------------------------------------------------------

---------------------------------------------------------------------------
       |                      シングル ユース サーバー
       |          (各アクティブ化要求に対して新しいプロセスを作成)
       |                       アクティブ化モード
       |-------------------------------------------------------------------
       |   対話ユーザー    | "このユーザー"    |"起動したユーザー" | Win32
Client |                   |  として           | として            | サービス
Local  | 常に対話型ウィン  | 常に新しいウィン  | 常にクライアント  | なし (可能なアク
       | ドウ ステーション | ドウ ステーション | プロセスのウィン  | ティブ化は 1 つ
       | でプロセス起動。  | でプロセス起動。  | ドウ ステーション | だけ)
       | 対話型ウィンドウ  |                   | でプロセス起動。  | 
       | ステーションがな  |                   |                   |
       | ければアクティブ  |                   |                   |
       | 化失敗。          |                   |                   |
-------|                   |                   |-------------------|
Remote |                   |                   | クライアントの    |
       |                   |                   | SID と LUID の両  |
       |                   |                   | 方が以前のクライ  |
       |                   |                   | アントのアクティ  |
       |                   |                   | ブ化と一致すれば  |
       |                   |                   | 既存のウィンドウ  |
       |                   |                   | ステーションでプ  |
       |                   |                   | ロセス起動。それ  |
       |                   |                   | 以外は新しいウィ  |
       |                   |                   | ンドウステーション|
---------------------------------------------------------------------------

ウィンドウ ステーションと Windows NT リソース

ここでは、Windows NT で新しいウィンドウ ステーションを作成する際の注意点、およびそれが COM サーバーの構成に及ぼす影響について検討します。この後見ていくように、Windows NT コンピュータ上で作成できるウィンドウ ステーションの数には制限があります。その制限を超えると、Windows NT で COM がサーバー プロセスの新しいインスタンスを起動する際にエラーが発生します。一般的には、次のようなエラー メッセージが表示されます。
DLL 初期化の失敗
ダイナミック リンク ライブラリ d:\winnt\system32\kernel32.dll の初期化に失敗しました。
プロセスは異常終了します。
Windows NT では、各ウィンドウ ステーションには、対応するデスクトップが 1 つ以上あります。Windows NT は、デスクトップ上で実行されるすべての Windows アプリケーションに対して、特殊なメモリ ヒープを使用します。デフォルトでは、各デスクトップ ヒープは 3 MB のメモリを消費します。Windows NT には、デスクトップ ヒープの作成には 48 MB という制限があり、この値は設定不可能です。これは、Windows NT コンピュータで作成できるウィンドウ ステーションの最大数が 16 であることを意味します (ウィンドウ ステーションは複数のデスクトップを持つ可能性があるため、おそらくはさらに少なくなります)。この数を増やすため、レジストリ エディタを使用してレジストリを編集することで、デフォルトのデスクトップのヒープ サイズを小さくすることができます。

警告 : レジストリ エディタの使い方を誤ると、システム全体に及ぶ深刻な問題が発生することがあります。最悪の場合、問題を修正するために Windows NT の再インストールが必要になることがあります。マイクロソフトは、レジストリ エディタの誤用により発生した問題に関しては、一切責任を負わないものとします。レジストリ エディタは、自己の責任においてご使用ください。

編集する名前付きの値は、次のキーの下にあります。
   HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session
   Manager\SubSystems
"Windows" という名前付きの値を編集する必要があります。この値は REG_SZ 文字列です。この文字列で "Shared Section=1024,3072" という部分を探します。この部分を "Shared Section=1024,3072,512" となるように変更します。この変更を有効にするには、コンピュータを再起動する必要があります。この変更を加えることにより、対話型ウィンドウ ステーションのデスクトップに対しては 3 MB (デフォルト) のヒープ サイズ、非対話型デスクトップに対しては 512 KB を指定することになります (最初のパラメータは使用されなくなっていますが変更しないでください)。この変更により、48 MB / 512 KB つまり 96 個近くのウィンドウ ステーションが可能になります。

注 : 1 つのウィンドウ ステーション内に複数のデスクトップを含めることができます。上記の "起動したユーザー" のサーバーに関する説明では、ローカル クライアント プロセスのウィンドウ ステーションと表現した場合、"ウィンドウ ステーションとデスクトップ" の短縮形と見なす必要があります。"起動したユーザー" の設定は、実際は DCOM 未対応のレガシ サーバー用のものであり、めったに使用されません。このようなレガシ サーバーでは、それ独自のデスクトップでの実行が想定されています。このため、MULTIPLEUSE の "起動したユーザー" のサーバーでは、同一のウィンドウ ステーション内の異なるデスクトップの各クライアント プロセスによって、そのウィンドウ ステーションやデスクトップで起動される新しいサーバー プロセスが作成されます。SINGLEUSE の "起動したユーザー" のサーバーでは、やはりサーバーがクライアント プロセスのウィンドウ ステーションとデスクトップを継承します。

Windows NT 4.0 Service Pack 4.0 では、COM はウィンドウ ステーションを再利用しようとします。これ以前のバージョンでは、サーバーが特定のユーザーで実行されるように設定され、サーバー プロセスの複数のインスタンスが起動されている場合、各プロセスがその独自のウィンドウ ステーションを取得します。これが原因で、上述したウィンドウ ステーションの制限に到達します。SP4 では、COM は、同じユーザー ID (またはトークン) として実行するように設定されている、すべての RunAs (つまり、 "アクティベータとしてアクティベート" または "起動したユーザー" でない) サーバーを、同じウィンドウ ステーションで作成しようとします。

これにより、同じトークンで複数のサーバー プロセスが実行される場合に、デスクトップのヒープ サイズを調整する必要がなくなります。使用している構成で、すべてのサーバーが同じユーザーで実行するように設定されている場合、または同じ RunAs サーバー プロセスの複数のインスタンスが実行される場合は、 上記の手順で デスクトップ ヒープ サイズを減らさないでください。この場合は、デフォルト値 (3 MB) のままにしておくことを推奨します。これは、デスクトップ ヒープを小さくすると、システムはより多くのウィンドウ ステーションやデスクトップを作成できますが、ウィンドウ ステーションやデスクトップ内で実行できるプロセスの数は徐々に小さくなるためです。

これに対して、異なるトークンで実行している複数のサーバーがある構成の場合は、ウィンドウ ステーションの制限に直面することになります。この場合は、この資料の記述に従って、デスクトップ ヒープ サイズを小さくする必要があります。

関連情報

デスクトップ ヒープ サイズの問題の関連情報については、次の「サポート技術情報」 (Microsoft Knowledge Base) の資料を参照してください。

142676 Overcoming User32.dll Initialization Failure Errors
142676 User32.dll の初期化失敗エラーへの対処方法

関連情報

この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 169321 (最終更新日 1999-10-23) をもとに作成したものです。

プロパティ

文書番号: 169321 - 最終更新日: 2005年7月11日 - リビジョン: 3.1
この資料は以下の製品について記述したものです。
  • Microsoft OLE 4.0を以下の環境でお使いの場合
    • Microsoft Platform SDK January 2000 Edition
キーワード:?
kbapi kbcomt kbdcom kbenv kbgrpdscom kbgrpdskernbase kbinfo kbinterop kbkernbase kbprogramming kbsdkwin32 kbusage KB169321
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com