シェル名前空間の概要
シェル 名前空間 は、シェルによって管理されるファイル システムおよびその他のオブジェクトを 1 つのツリー構造階層に整理します。 概念的には、ファイル システムのより大規模で包括的なバージョンです。
はじめに
シェルの主な役割の 1 つは、システムを構成するさまざまなオブジェクトの管理とアクセスの提供です。 これらのオブジェクトの中で最も多く使い慣れているのは、コンピューター のディスク ドライブに存在するフォルダーとファイルです。 ただし、シェルは多数の非ファイル システムまたは 仮想 オブジェクトも管理します。 次に例をいくつか示します。
- ネットワーク プリンター
- その他のネットワークコンピューター
- コントロール パネル アプリケーション
- ごみ箱
一部の仮想オブジェクトには、物理ストレージはまったく含まれません。 たとえば、プリンター オブジェクトには、ネットワーク接続されたプリンターへのリンクのコレクションが含まれています。 ごみ箱などの他の仮想オブジェクトには、ディスク ドライブに格納されているデータが含まれている場合がありますが、通常のファイルとは異なる方法で処理する必要があります。 たとえば、仮想オブジェクトを使用して、データベースに格納されているデータを表すことができます。 名前空間に関しては、データベース内のさまざまな項目が Windows エクスプローラーに個別のオブジェクトとして表示されることがあります。ただし、これらはすべて 1 つのディスク ファイルに格納されています。
仮想オブジェクトは、リモート コンピューター上に配置される場合もあります。 たとえば、ローミングを容易にするために、ユーザーのドキュメント ファイルがサーバーに格納される場合があります。 ユーザーが複数のデスクトップ PC からファイルにアクセスできるようにするには、現在使用しているデスクトップ PC の [マイ ドキュメント] フォルダーが、デスクトップ PC のハード ディスクではなくサーバーを指します。 そのパスには、マップされたネットワーク ドライブまたは UNC パス名が含まれます。
ファイル システムと同様に、名前空間には、フォルダーとファイルの 2 つの基本的な種類のオブジェクトが含まれています。 Folder オブジェクトはツリーの ノード です。これらは、ファイル オブジェクトやその他のフォルダーのコンテナーです。 ファイル オブジェクトはツリーの 葉 です。通常のディスク ファイルまたはプリンター リンクなどの仮想オブジェクトです。 ファイル システムに含まれていないフォルダーは、 仮想フォルダーと呼ばれることがあります。
ファイル システム フォルダーと同様に、仮想フォルダーのコレクションは通常、システムによって異なります。 仮想フォルダーには、次の 3 つのクラスがあります。
- すべてのシステムに存在する標準の仮想フォルダー (ごみ箱など)。
- 標準の名前と機能を備えているが、すべてのシステムに存在しない場合があるオプションの仮想フォルダー。
- ユーザーがインストールする標準以外のフォルダー。
ファイル システム フォルダーとは異なり、ユーザーは新しい仮想フォルダー自体を作成できません。 Microsoft 以外の開発者によって作成されたもののみをインストールできます。 したがって、仮想フォルダーの数は通常、ファイル システム フォルダーの数よりもはるかに少なくなります。 仮想フォルダーを実装する方法については、「 名前空間拡張機能」を参照してください。
Windows エクスプローラーの [エクスプローラー バー] で名前空間の構造を視覚的に表現できます。 たとえば、次の Windows エクスプローラーのスクリーン ショットは、比較的単純な名前空間を示しています。
名前空間階層の最終的なルートはデスクトップです。 ルートのすぐ下には、[マイ コンピューター] や [ごみ箱] などの複数の仮想フォルダーがあります。
さまざまなディスク ドライブのファイル システムは、より大きな名前空間階層のサブセットと見なすことができます。 これらのファイル システムのルートは、[マイ コンピューター] フォルダーのサブフォルダーです。 マイ コンピューターには、マップされたネットワーク ドライブのルートも含まれます。 ツリー内の他のノード (マイ ドキュメントなど) は仮想フォルダーです。
名前空間オブジェクトの識別
名前空間オブジェクトを使用する前に、まずそれを識別する方法が必要です。 ファイル システム内のオブジェクトには、MyFile.htmなどの名前を指定できます。 システム内の他の場所にその名前のファイルが存在する可能性があるため、ファイルまたはフォルダーを一意に識別するには、"C:\MyDocs\MyFile.htm" などの完全修飾パスが必要です。 このパスは基本的に、ファイル システム ルート C:\からパス内のすべてのフォルダーの順序付きリストであり、ファイルで終わる。
名前空間のコンテキストでは、パスは、名前空間のファイル システム部分にあるオブジェクトを識別するのに引き続き非常に役立ちます。 ただし、仮想オブジェクトには使用できません。 代わりに、シェルは、任意の名前空間オブジェクトで使用できる別の識別手段を提供します。
アイテム ID
フォルダー内では、各オブジェクトには アイテム ID があり、これはファイル名またはフォルダー名と同等の機能を持ちます。 項目 ID は実際には 、SHITEMID 構造体です。
typedef struct _SHITEMID {
USHORT cb;
BYTE abID[1];
} SHITEMID, * LPSHITEMID;
abID メンバーはオブジェクトの識別子です。 abID の長さは定義されておらず、その値は オブジェクトを含むフォルダーによって決まります。 abID 値がフォルダーによってどのように割り当てられるかについての標準定義がないため、関連付けられたフォルダー オブジェクトに対してのみ意味があります。 アプリケーションでは、特定のフォルダー内のオブジェクトを識別するトークンとして扱う必要があります。 abID の長さは異なるため、cb メンバーは、SHITEMID 構造体のサイズをバイト単位で保持します。
アイテム ID は表示目的では役に立たないため、オブジェクトを含むフォルダーには通常、表示名が割り当てられます。 これは、フォルダーの内容を表示するときに Windows エクスプローラーによって使用される名前です。 表示名の処理方法の詳細については、「 フォルダーから情報を取得する」を参照してください。
アイテム ID リスト
アイテム ID が単独で使用されることはほとんどありません。 通常、ファイル システム パスと同じ目的を果たすアイテム ID リストの一部です。 ただし、パスに使用される文字列の代わりに、項目 ID リストは ITEMIDLIST 構造体です。 この構造体は、2 バイトの NULL で終わる 1 つ以上の項目 ID の順序付きシーケンス です。 アイテム ID リスト内の各項目 ID は、名前空間オブジェクトに対応します。 その順序は、ファイル システム パスと同様に、名前空間内のパスを定義します。
次の図は、C:\MyDocs\MyFile.htmに対応する ITEMIDLIST 構造体の概略図を示しています。 各項目 ID の表示名は、その上に表示されます。 abID メンバーのさまざまな幅は任意です。これは、このメンバーのサイズが異なる可能性があることを示しています。
PIDL
シェル API の場合、名前空間オブジェクトは通常、 ITEMIDLIST 構造体へのポインター、または項目識別子リスト (PIDL) へのポインターによって識別されます。 便宜上、PIDL という用語は一般に、このドキュメントでは、構造体へのポインターではなく、構造体自体を参照します。
前の図に示した PIDL は、 完全な PIDL または 絶対 PIDL と呼ばれます。 完全な PIDL はデスクトップから開始され、パス内のすべての中間フォルダーの項目 ID が含まれます。 オブジェクトの項目 ID の後に終端の 2 バイト の NULL が続きます。 完全な PIDL は完全修飾パスに似ていて、シェル名前空間内のオブジェクトを一意に識別します。
完全な PIDL は頻繁に使用されません。 多くの関数とメソッドでは、 相対 PIDL が必要です。 相対 PIDL のルートは、デスクトップではなくフォルダーです。 相対パスと同様に、構造体を構成する一連の項目 ID によって、2 つのオブジェクト間の名前空間内のパスが定義されます。 オブジェクトは一意に識別されませんが、通常は完全な PIDL よりも小さく、多くの目的に十分です。
最も一般的に使用される相対 PIDL ( 単一レベルの PIDL) は、オブジェクトの親フォルダーに対する相対パスです。 オブジェクトの項目 ID と終了 NULL のみが含まれます。 複数レベルの PIDL は、多くの目的にも使用されます。 アイテム ID は 2 つ以上含まれており、通常は親フォルダーからオブジェクトへのパスを、一連の 1 つ以上のサブフォルダーを介して定義します。 単一レベルの PIDL は引き続き完全修飾 PIDL であることに注意してください。 特に、デスクトップ オブジェクトはデスクトップの子であるため、完全修飾 PIDL に含まれる項目 ID は 1 つだけです。
「フォルダーの ID を取得する」で説明したように、シェル API には、オブジェクトの PIDL を取得するさまざまな方法が用意されています。 これを取得したら、通常は、他のシェル API 関数とメソッドを呼び出すときにオブジェクトを識別するために使用します。 このコンテキストでは、PIDL の内部コンテンツは不透明で無関係です。 この説明では、PIDL を特定の名前空間オブジェクトを表すトークンと考え、一般的なタスクに使用する方法に焦点を当てます。
PIDL の割り当て
PIDL はパスと似ていますが、使用するには若干異なるアプローチが必要です。 主な違いは、メモリを割り当てて割り当て解除する方法です。
パスに使用される文字列と同様に、PIDL にメモリを割り当てる必要があります。 アプリケーションが PIDL を作成する場合は、 ITEMIDLIST 構造体に十分なメモリを割り当てる必要があります。 ここで説明するほとんどの場合、シェルは PIDL を作成し、メモリ割り当てを処理します。 PIDL の割り当てに関係なく、アプリケーションは通常、PIDL が不要になったときに割り当てを解除する必要があります。
CoTaskMemAlloc 関数を使用して PIDL を割り当て、CoTaskMemFree 関数を使用して割り当てを解除します。