プロパティ ハンドラーのベスト プラクティスと FAQ

このトピックでは、Windows プロパティ システムを操作するためのプロパティ ハンドラーを作成および登録する方法について説明します。

このトピックは次のように整理されています。

ベスト プラクティス

ファイル システムプロパティのオーバーライド

ファイルのプロパティの一部は、ファイル システム のデータ ソースによって提供されます。次に例を示します。

  • PKEY_FileName
  • PKEY_Extension
  • PKEY_ModifiedTime

一般に、プロパティ ハンドラーは、これらのプロパティの値を指定できません。 ただし、場合によっては、プロパティ ハンドラーによって提供される登録情報に基づいて、これらのプロパティをオーバーライドできます。 プロパティ ハンドラーは\CLSID{handler clsid\}\OverrideFileSystemProperties HKEY_CLASSES_ROOTオーバーライドするプロパティの名前を設定します。 これは、システムがナレッジを持つ、次の一覧に示されている固定のプロパティ セットに限定されます。

オーバーライドは、次のプロパティ値でサポートされています。

すべてのシェル プロパティの完全な一覧については、「 シェル プロパティ」を参照してください。

重要

オーバーライドされたプロパティ値は、ファイルのインデックスが作成されている場合にのみ使用されます。 したがって、ファイル システム データ ソースからファイルを参照しても、オーバーライドされた値は表示されません。  

XML ベースのファイル形式でのプロパティの格納

XML ベースのファイル形式でプロパティを格納するには、次の 2 つの基本的なオプションがあります。

  • ドキュメントの XML スキーマに従って、XML 要素と属性を使用して各プロパティを格納します。 この方法は、より "XML に優しい" 方法です。
  • プロパティ ストア全体をメモリ バイナリ ラージ オブジェクト (BLOB) にシリアル化し、BLOB を base64 でエンコードされた文字列に変換し、その文字列を XML に格納します。 これは 2 つのアプローチの方が簡単であり、開いているメタデータのサポートを簡単に提供するために使用できます。

一部のハンドラーでは、これらのアプローチを組み合わせて、いくつかの重要な値を標準 XML 形式で格納し、残りの値を BLOB に格納する場合があります。たとえば、

計算されたプロパティ

一部のプロパティは、ファイルの特定の属性から派生します。 たとえば、 System.Image.Dimensions プロパティは、イメージ ファイル内のイメージの実際のディメンションによって決まります。 このようなプロパティ値はプロパティ ハンドラーで変更できないため、プロパティの説明でマーク isInnate="true" されます。 その他のプロパティは、特定のプロパティの一部から、または複数のプロパティの値を集計することによって計算されます。 これらの "計算済み" プロパティを更新すると、"source" 値を変更する方法があいまいになるため、計算されたプロパティはプロパティの説明でマーク isInnate="true" するか、読み取り専用として報告する必要があります。 後者のオプションは、 IPropertyStoreCapabilities::IsPropertyWritable からS_FALSEを返すようにハンドラーに指示することで使用できます。

よく寄せられる質問

プロパティ ハンドラーが Windows Search インデクサーによって読み込まれないのはなぜですか?

Windows Search インデクサーはシステム サービスとして実行され、ユーザー プロファイル ディレクトリに格納されている DLL を読み込むことができません。 Microsoft Visual Studio を使用してビルドおよびデバッグを行う場合は、DLL がユーザー プロファイルに配置されます (したがって、インデクサーによって読み込まれません)。 これを回避するには、プロファイル フォルダーの外部 (たとえば 、C:\Program Files\YourAppName) の外部に DLL をコピーし、そこに登録します。

Windows Search インデクサーを操作するためのプロパティ ハンドラーの開発に関するより具体的なガイダンスについては、「Windows Search のプロパティ ハンドラーの開発」を参照してください。

'IPropertyStore::GetCount' 列挙メソッドと 'IPropertyStore::GetAt' 列挙メソッドを使用して検出できるプロパティはどれですか?

プロパティ ストア オブジェクトのすべてのクライアントでこれらのメソッドが使用されるわけではありません。 一部のクライアントは、(PKEY 名で) 直接要求する予定のプロパティを認識しているか、プロパティの説明リストを通じてプロパティ情報を受け取ります。 プロパティ検出メソッドは、他のいくつかのシナリオをサポートします。 プロパティがこれらのシナリオに参加する必要がない場合は、列挙する必要はありません。 そのため、プロパティ ハンドラーは、 IPropertyStore::GetCount メソッドと IPropertyStore::GetAt メソッドを使用して検出されないプロパティに 対して、 VT_EMPTY以外の値を生成できます。

ただし、次のいずれかの条件が満たされている場合は、これらのメソッドを使用してプロパティを表示する必要があります。

  • プロパティが検索できるようにインデックスが作成されている場合: つまり、Windows Search プロパティ ストア (プロパティの説明スキーマで示されます isColumn = "true" ) に含まれているか、フルテキスト検索 (inInvertedIndex = "true") で使用できます。 これらのフラグがない場合、またはプロパティの説明がない場合は、検索を有効にするために、型 "string" のプロパティが反転インデックスに自動的に追加されます。 プロパティ システムの既知のプロパティ (プロパティの説明がインストールされているもの) の一覧は非常に大きいため (800 を超えるプロパティ)、プロパティ システムに登録されているすべてのプロパティに対してすべてのプロパティ ハンドラーを要求するのは現実的ではありません。 代わりに、インデックス作成プロセスは、インデックスを作成する各項目のプロパティ ハンドラーから関連するプロパティを列挙し、列挙プロパティの値を使用してフルテキスト インデックスを作成します。
  • アイテムのプロパティ セットが複製されたときにプロパティをコピーする必要がある場合: "プロパティ セットのコピー" 関数を実装するために、コピーする必要があるプロパティは 、IPropertyStore::GetCount メソッドと IPropertyStore::GetAt メソッドを通じて表示されます。 コピーする必要がないプロパティやコピーに意味がないプロパティは含めないでください。
  • プロパティ値が空でない場合 (VT_EMPTY): 空のプロパティ値は、クライアントには役に立ちません。 クライアントが空のプロパティ値を返そうとすると、VT_EMPTYの値が返されます。 したがって、空の値を持つプロパティは列挙しないでください。
  • "プロパティの削除" 関数を呼び出すときに プロパティを削除する必要がある場合: この機能は、プライバシーを保護するために存在します。列挙を介してプロパティ ハンドラーからすべての値を検出し、ユーザーが削除するために選択した各値を削除します。

Note

プロパティを列挙しても、ハンドラーが固定スキーマをサポートしている場合 (開いているメタデータではなく) 特定のプロパティ ハンドラーがサポートするプロパティのセットは伝達されません。 代わりに、このようなハンドラーは、サポートされているプロパティのセットを文書化する必要があります。

 

開いているメタデータをサポートするファイル形式操作方法知っていますか?

開いているメタデータのサポートについては、「ファイルの種類」の「Open Metadata をサポートする ファイルの種類」を参照してください。

プロパティ ハンドラー VT_NULL使用して値を格納できますか?

いいえ。 VT_NULL値は、IPropertyStore::GetValue および IPropertyStore::SetValue の呼び出しでVT_EMPTYに変換されます。

'PropVariantChangeType' 関数でサポートされている日付文字列形式はどれですか?

一般に、日付/時刻値を表すプロパティは、VT_FILETIMEを使用して表す必要があります。 ただし、多くのデータ ソースでは、この情報が文字列形式で提供されます。 PropVariantChangeType ヘルパー API では、次の表に示すように、一部の文字列日付形式を FILETIME 値に強制変換できます。

フォーマット Windows Vista、Windows XP、Microsoft Windows Desktop Search (WDS) Windows 7 メモ
yyyy/mm/dd:hh:mm:ss.uuu はい はい Utc;y=year、m=month、d=date、h=hours (24 時間制)、m=minutes、s=seconds、u=microseconds
yyyy-mm-ddThh:mm:ssZ いいえ はい ISO8601 形式の仕様UTC ('Z' タイム ゾーン インジケーターで示されます);y=year、m=month、d=date、h=hours (24 時間制)、m=minutes、s=seconds;'T' は時間部分の区切り記号です。

読み取り専用プロパティ ハンドラーを作成できますか?

はい。 一部のプロパティ ハンドラー実装では、プロパティ値の書き込みがサポートされていません。 これらのプロパティ ハンドラーは、STGM_READWRITEを渡す IInitializeXXX::Initialize の呼び出し、または IPropertyStore::SetValue の呼び出しでSTGM_E_ACCESSDENIEDを返す必要があります。

STGM_READ モードで開かれたすべてのプロパティ ハンドラーは、 IPropertyStore::SetValue の呼び出しでSTGM_E_ACCESSDENIEDを返す必要があります。

プロパティ ハンドラーは、スキーマがプロパティが書き込み可能であることを示している場合でも、プロパティを読み取り専用として扱うことができますか?

はい。 スキーマ システムでは、プロパティには読み取り専用 (を含む) または読み取り/書き込みとして注釈が付 isInnate = "true"いています。 スキーマが書き込み可能であると言う特定のプロパティの書き込みをサポートしていないプロパティ ハンドラーは、 IPropertyStoreCapabilities を実装し、そのプロパティの IPropertyStoreCapabilities::IsPropertyWritable の呼び出しでS_FALSEを返す必要があります。 これは、このハンドラーとこのファイルのコンテキストでは、 プロパティが書き込み不可能であることを示します。

Note

逆のアクションは実行できません。 スキーマで読み取り専用としてマークされたプロパティをプロパティ ハンドラーが書き込むのを有効にすることはできません