Windows Search のプロパティ ハンドラーの開発

Microsoft Windows Search では、プロパティ ハンドラーを使用して項目からプロパティの値を抽出し、プロパティ システム スキーマを使用して、特定のプロパティのインデックスを作成する方法を決定します。 プロパティ値の読み取りとインデックス作成を行う際、セキュリティと堅牢性を向上させるために、プロパティ ハンドラーは Windows Search によってアウトプロセスで呼び出されます。 これに対し、エクスプローラーでプロパティ値の読み取りと書き込みを行うときは、プロパティ ハンドラーはインプロセスで呼び出されます。

このトピックは、プロパティ システムのトピックを Windows Search 固有の情報で補完するもので、次のセクションが含まれています。

 

プロパティ ハンドラーの設計に関する決定事項

プロパティ ハンドラーの実装には、次の手順が含まれます。

  1. サポートするプロパティに関する設計上の決定を行う。
  2. プロパティ システムにまだ含まれていないプロパティのプロパティ記述 (.propdesc) ファイルを作成する。
  3. プロパティ ハンドラーを実装してテストする。
  4. プロパティ ハンドラーとプロパティ記述ファイルをインストールして登録する。
  5. プロパティ ハンドラーのインストールと登録をテストする。

開始する前に、設計に関する以下の質問について検討する必要があります。

  • ファイル形式でサポートされている (する必要がある) プロパティは何ですか?
  • これらのプロパティはシステム スキーマに既に含まれていますか?
  • 既存のシステム提供のプロパティ ハンドラーを使用できますか?
  • エンド ユーザーに表示できるプロパティはどれですか?
  • ユーザーが編集できるプロパティはどれですか?
  • フルテキスト検索のサポートを、プロパティ ハンドラーまたはフィルターで提供する必要がありますか?
  • レガシ アプリケーションをサポートする必要がありますか? その必要がある場合、何を実装すればよいですか?

Note

続行する前に、「システム提供のプロパティ ハンドラーの使用」を参照し、システム提供のプロパティ ハンドラーを使用して、時間と開発リソースの両方を節約できるかどうかを確認してください。

 

これらの決定を行った後、Windows Search エンジンがファイルとプロパティのインデックス作成を開始できるように、カスタム プロパティの正式な記述を作成できます。 これらの正式な記述は XML ファイルであり、「プロパティ記述スキーマ」で説明しています。

プロパティに関する決定事項

サポートするプロパティを検討する際、ユーザーのインデックス作成と検索のニーズを特定する必要があります。 たとえば、ファイルの種類に役立つ可能性のあるプロパティを 100 個特定できますが、ユーザーはごく少数だけの検索に関心がある場合があります。 さらに、それらのプロパティの大小さまざまなグループをエクスプローラーでユーザーに表示し、表示されているそれらのプロパティのサブセットのみユーザーが編集できるようにしたい場合があります。

お使いファイルの種類では、ユーザー定義の任意のカスタム プロパティと、システム定義プロパティのセットをサポートできます。 カスタム プロパティを作成する前に、システム プロパティを調べて、サポートするプロパティがシステム プロパティによって既に定義されているかどうかを確認してください。 常に、最も重要なシステム定義のプロパティをサポートするようにしてください。

プロパティの設計に役立つ以下のマトリックスを使用することをお勧めします。

プロパティ名 インデックス可能 表示可能 編集可能
property1 N
property... N
propertyn N N N

 

これらの各プロパティについて、必要な属性を決定し、プロパティ記述 XML ファイル (.propdesc) でそれらを正式に記述する必要があります。 属性には、プロパティのデータ型、ラベル、ヘルプ文字列などが含まれます。 インデックス可能なプロパティの場合は、プロパティ記述ファイルの searchInfo XML 要素にある次のプロパティ属性に特に注意する必要があります。

属性 説明
inInvertedIndex 省略可能。 文字列プロパティ値を単語に分割し、各単語を反転されたインデックスに格納するかどうかを示します。 反転されたインデックスを使用すると、プロパティ値で単語や語句を効率的に検索できます。その際、CONTAINS または FREETEXT を使用します (たとえば、SELECT ...WHERE CONTAINS "sometext")。 FALSE に設定すると、文字列全体に対して検索が行われます。 ほとんどの文字列プロパティでは、これを TRUE に設定する必要があります。文字列以外のプロパティでは、これを FALSE に設定する必要があります。 既定値は FALSE です。
isColumn 省略可能。 プロパティを列として Windows Search データベースに格納するかどうかを示します。 プロパティを列として格納すると、列値全体での取得、並べ替え、グループ化、フィルター処理 (つまり、CONTAINS または FREETEXT を除く任意の述語の使用) が可能になります。 反転されたインデックスで検索される非常に大きなテキスト プロパティ (ドキュメントの本文など) でない限り、ユーザーに表示されるプロパティでは、これを TRUE に設定する必要があります。 既定値は FALSE です。
isColumnSparse 省略可能。 値が NULL の場合に、プロパティがスペースを取らないかどうかを示します。 非スパース プロパティは、値が NULL の場合でも、すべての項目にスペースを取ります。 プロパティが複数値の場合、この属性は常に TRUE になります。 この属性は、すべての項目に値が存在する場合にのみ FALSE にする必要があります。 既定は TRUE です。
columnIndexType 省略可能。 クエリを最適化するために、Windows Search エンジンでは、isColumn=TRUE が設定されているプロパティのセカンダリ インデックスを作成できます。 これにより、インデックス作成中に必要な処理とディスク領域は増えますが、クエリ時のパフォーマンスは向上します。 プロパティがユーザーによって頻繁に並べ替え、グループ化、またはフィルター処理される (つまり、=、!=、<、>、LIKE、MATCHES を使用する) 傾向がある場合、この属性は "OnDisk" に設定する必要があります。 既定値は "NotIndexed" です。 次の値が有効です。
  • NotIndexed: セカンダリ インデックスは作成されません。
  • OnDisk: セカンダリ インデックスを作成してディスクに格納します。
maxSize 省略可能。 Windows 検索データベースに格納されているプロパティ値に許容される最大サイズを示します。 この制限は、ベクトル全体ではなく、ベクトルの個々の要素に適用されます。 このサイズを超える値は切り捨てられます。 既定値は "128" (バイト) です。
現在、Windows Search では、ファイルから受け入れるデータの量を計算するときに maxSize は使用されません。 代わりに、Windows Search で使用される制限は、ファイルのサイズと、HKEY_LOCAL_MACHINE->Software->Microsoft->Windows Search->Gathering Manager->MaxGrowFactor のレジストリから読み取られる MaxGrowFactor の積 (ファイル サイズ N * MaxGrowFactor) です。 既定の MaxGrowFactor は 4 です。 したがって、ファイルの種類について、その合計サイズは小さいが、大きいプロパティが含まれている場合、Windows Search では、出力するすべてのプロパティ データを受け入れない可能性があります。 ただし、ニーズに合わせて MaxGrowFactor を増やすことができます。

 

Note

columnIndexType 属性では、より高速なクエリがもたらす利点と、セカンダリ インデックスによって発生する可能性のあるインデックス作成時間と領域コストの増加を比較検討する必要があります。 ただし、このコストは null 以外の値を持つ項目に対してのみ発生するので、ほとんどのプロパティでこの属性を "OnDisk" に設定できます。

 

フルテキストのサポート

一般に、フルテキスト検索は、フィルターと呼ばれるコンポーネントでサポートされていますが、単純なファイル形式のテキスト ベースのファイルの種類では、プロパティ ハンドラーの方が、少ない開発作業でこの機能を提供できる場合があります。 ファイルの種類に最適なものを決定できるように、「フルテキスト コンテンツ」のセクションを参照して、フィルターとプロパティ ハンドラーの機能の比較について確認してください。 特に重要なのは、フィルターがファイルごとに複数の言語コード識別子 (LCID) を処理できるのに対し、プロパティ ハンドラーはできないということです。

Note

プロパティ ハンドラーは、フィルターのようにコンテンツをチャンクできないため、大きなファイル (複雑でないファイル形式の場合でも) をメモリに完全に読み込む必要があります。

 

オペレーティング システムの実装に関する考慮事項

Windows 7 の実装情報

Windows 7 以降には、プロパティ ハンドラー、IFilter、または新しい拡張機能を登録するときの新しい動作があります。 新しいプロパティ ハンドラーや IFilter がインストールされると、対応する拡張子を持つファイルのインデックスが自動的に再作成されます。

Windows 7 では、IFilter を対応するプロパティ ハンドラーと組み合わせてインストールし、IFilter をプロパティ ハンドラーの前に登録することをお勧めします。 プロパティ ハンドラーを登録すると、最初に再起動を必要とせずに、以前にインデックス付けされたファイルのインデックス再作成がすぐに開始され、コンテンツのインデックス作成のために以前に登録された IFilter が利用されます。

対応するプロパティ ハンドラーなしで IFilter のみインストールされている場合、インデックス作成サービスの再起動後またはシステムの再起動後に、自動インデックス再作成が行われます。

Windows 7 に固有のプロパティ記述フラグについては、次のリファレンス トピックを参照してください。

Windows Vista 以前の実装情報

Windows Vista より前のフィルターでは、ファイル コンテンツとプロパティの解析と列挙のサポートが提供されていました。 プロパティ システムの導入により、プロパティ ハンドラーはファイル プロパティを処理し、フィルターはファイル コンテンツを処理します。 Windows Vista では、「Windows Search でフィルター ハンドラーを作成するためのベスト プラクティス」で説明されているように、プロパティ ハンドラーと連携して IFilter インターフェイスの部分的な実装のみ開発する必要があります。

プロパティ システムは Windows XP の Windows Search インストールにも含まれていますが、サード パーティおよびレガシ アプリケーションでは、フィルターでコンテンツとプロパティの両方を処理することが必要になる場合があります。 そのため、Windows XP プラットフォームで開発している場合は、完全なフィルター実装と、ファイルの種類またはカスタム プロパティのプロパティ ハンドラーを提供する必要があります。

 

プロパティ記述ファイルの作成

プロパティ記述 XML ファイル (.propdesc) の構造について、propertyDescription のトピックで説明しています。 検索で特に重要なのは、searchInfo 要素の属性です。. サポートするプロパティを決定したら、各プロパティのプロパティ記述ファイルを作成して登録する必要があります。 .propdesc ファイルを登録すると、それらはスキーマのプロパティ記述リストに含められ、検索エンジンのプロパティ ストア内で列名になります。

カスタム プロパティの記述は、スキーマ サブシステムの IPropertySystem::RegisterPropertySchema を呼び出すラッパー API である PSRegisterPropertySchema 関数を使用して登録できます。 この関数は、ローカル コンピューター上の .propdesc ファイルのファイル パス (通常は "Program Files" の下にあるアプリケーションのインストール ディレクトリ) を使用して、プロパティ記述スキーマ (.propdesc) ファイルの追加をスキーマ サブシステムに通知します。 通常、セットアップまたはアプリケーション (プロパティ ハンドラー インストーラーなど) は、.propdesc ファイルをインストールした後にこのメソッドを呼び出します。

 

プロパティ ハンドラーの実装

プロパティ ハンドラーの開発では、次のインターフェイスの実装が必要になります。

  • IInitialzeWithStream: プロパティ ハンドラーのストリームベースの初期化を提供します。
  • IPropertyStore: プロパティ値を列挙、取得、設定します。
  • IPropertyStoreCapabilities: オプション。 ユーザーが、ユーザー インターフェイスからプロパティを編集できるかどうかを識別します。

IInitializeWithStream

プロパティ システム」のトピックで説明しているように、ストリーム ベースの初期化を行うには、IInitializeWithStream を使用してプロパティ ハンドラーを実装することを強くお勧めします。 IInitializeWithStream を実装しないことを選択した場合、プロパティ ハンドラーのレジストリ キーに DisableProcessIsolation フラグを設定して、プロパティ ハンドラーで分離プロセスでの実行をオプトアウトする必要があります。 プロセスの分離の無効化は、通常、レガシ プロパティ ハンドラーのみを対象としており、新しいコードでは極力避ける必要があります。

IPropertyStore

プロパティ ハンドラーを作成するには、次のメソッドを使用して IPropertyStore インターフェイスを実装する必要があります。

メソッド 説明
Commit プロパティの変更をファイルに保存します。
GetAt 項目のプロパティ配列からプロパティ キーを取得します。
GetCount ファイルに添付されているプロパティの数を取得します。
GetValue 特定のプロパティのデータを取得します。
SetValue 新しいプロパティ値を設定するか、既存の値を置換または削除します。

 

 

 

このインターフェイスを実装するための重要な考慮事項が、IPropertyStore のドキュメントに記載されています。

Note

プロパティ ハンドラーが特定の項目の同じプロパティに対して複数の値を出力する場合、出力された最後の値のみがカタログに格納されます。

 

 

IPropertyStoreCapabilities

プロパティ ハンドラーは、必要に応じてこのインターフェイスを実装して、ユーザーが特定のプロパティを編集できないようにすることができます。 これらのプロパティは通常、[詳細] ページおよびペインで編集できますが、実装を行っているプロパティ ハンドラーでは編集できません。 このインターフェイスを正しく実装すると、代替方法 (つまり、シェルからの単純な実行時エラー) よりも優れたユーザー エクスペリエンスが提供されます。

 

項目のインデックスが作成されていることの確認

プロパティ ハンドラーを実装したので、ハンドラーが登録されている項目のインデックスが作成されていることを確認する必要があります。 カタログ マネージャーを使用してインデックスの再作成を開始できます。また、クロール範囲マネージャーを使用して、インデクサーでクロールする URL を示す既定のルールを設定することもできます。 もう 1 つの方法として、Windows Search コード サンプルの ReIndex コード サンプルに従います。

詳細については、「カタログ マネージャーの使用」および「クロール範囲マネージャーの使用」を参照してください。

 

プロパティ ハンドラーのインストールと登録

プロパティ ハンドラーが実装されたら、それを登録し、そのファイル名拡張子をハンドラーに関連付ける必要があります。 次の例は、これを行うために必要なレジストリ キーと値を示しています。

HKEY_CLASSES_ROOT
   CLSID
      {<CLSID for property handler>}
         (Default) = <Property Handler Name>
         InProcServer32
            (Default) = <full path to property handler dll>
            ThreadingModel = <your threading model>
HKEY_LOCAL_MACHINE
   SOFTWARE
      Microsoft
         Windows
            CurrentVersion
               PropertySystem
                  PropertyHandlers
                     <.fileextention>
                        (Default) = {<CLSID for property handler>}

 

プロパティ ハンドラーのテストとトラブルシューティング

以下に、実行すべきテストの種類に関するアドバイスの一覧を示します。

  • ファイルの種類でサポートされているすべてのプロパティから出力が取得されているかどうかテストします。
  • 大きなプロパティ値を使用します。たとえば、HTML ドキュメントで大きなメタタグを使用します。
  • プロパティ ハンドラーがファイル ハンドルをリークしていないことを確認します。これを行うには、プロパティ ハンドラーから出力を取得した後に編集するか、ファイル プロパティを列挙する前後に oh.exe などのツールを使用します。
  • プロパティ ハンドラーに関連付けられているすべてのファイルの種類をテストします。 たとえば、HTML フィルターが .htm および .html のファイルの種類で動作することを確認します。
  • 破損したファイルでテストします。 プロパティ ハンドラーは正常に失敗する必要があります。
  • アプリケーションで暗号化がサポートされている場合は、プロパティ ハンドラーが暗号化されたテキストを出力しないことをテストします。
  • プロパティ ハンドラーがフルテキスト検索をサポートしている場合:
    • ファイル コンテンツで複数の特殊な Unicode 文字を使用して、その出力をテストします。
    • 非常に大きなドキュメントの処理をテストして、プロパティ ハンドラーが期待どおりに動作することを確認します。

インストールとセットアップのテスト

最後に、インストールとアンインストールのルーチンをテストする必要があります。

  • インストールは、失敗したインストールから回復する必要があります (たとえば、セットアップを取り消してから再起動する場合など)。
  • アンインストールでは、プロパティ ハンドラーに関連付られているすべてのファイルを削除する必要があります。
  • アンインストールでは、プロパティ ハンドラーのインストールに関連付けられているファイル以外のファイルを削除してはなりません。
  • プロパティ ハンドラーに関連付けられているレジストリ キーは、アンインストール時に削除する必要があります。
  • インストール ディレクトリからファイルが削除された場合でも、アンインストールは機能する必要があります。

プロパティ ハンドラーのトラブルシューティング

以下に、プロパティ ハンドラーの開発中に生じる一般的なエラーをいくつか示します。

  • ユーザー ディレクトリの下に .propdesc ファイルまたは DLL をインストールする。
  • 相対パスを使用してコンポーネントを登録する。
  • HKEY_LOCAL_MACHINE ではなく、HKEY_CURRENT_USER の下にコンポーネントを登録する。
  • 非ストリーム ハンドラーに DisableProcessIsolation を設定するのを忘れる。
  • インデックスが作成されていない場所にテスト ファイルを配置する。

プロパティ ハンドラーとインデクサーとの連携に問題がある場合、トラブルシューティングに役立つヒントをいくつか以下に示します。

  • プロパティ記述 (.propdesc ファイル) が必要に応じて、isColumn="true"、isViewable="true"、isQueryable="true" とマークされていることを確認します。
  • .propdesc ファイルがグローバルな場所にあることを確認します。
  • 絶対パスを使用して .propdesc ファイルを登録したことを確認します。
  • .propdesc ファイルの登録に関する失敗がイベント ログに記録されていないことを確認します。
  • DLL がグローバルな場所 (ユーザー プロファイルではなく) にあることを確認します。
  • DLL が HKEY_LOCAL_MACHINE\Software\Classes に登録されていることを確認します。
  • 完全なパス (または、システム アカウントで認識されている環境変数を使用して絶対パスに展開される REG_EXPAND_SZ 文字列) を使用して DLL が登録されていることを確認します。
  • プロパティ ハンドラーがエクスプローラーで動作することを確認します。
  • IInitializeWithStream を使用することをお勧めしますが、IInitializeWithFile または IInitializeWithItem を使用する必要がある場合は、DisableProcessIsolation を指定していることを確認してください。
  • [インデックスのオプション] コントロール パネルに、ファイルの種類がインデックス付きファイルの種類として一覧表示されていることを確認します。
  • テスト ファイルがインデックス付きの場所にあることを確認します。
  • プロパティ ハンドラーのインストール以降にテスト ファイルが変更されたことを確認します。

テスト ファイルがインデックス付きの場所にあり、インデクサーがその場所を既にクロールしている場合、ファイルのインデックス再作成をトリガーするには、何らかの方法でファイルを変更する必要があります。

 

システム提供のプロパティ ハンドラーの使用

Windows には、ファイルの種類の形式に互換性がある場合に使用できる、システム提供のプロパティ ハンドラーがいくつか含まれています。 これらの形式のいずれかを使用する新しいファイル拡張子を定義する場合は、ファイル拡張子のハンドラー クラス識別子 (CLSID) を登録することにより、システム提供のハンドラーを使用できます。

次の表に示す CLSID を使用して、ファイル形式の種類用のシステム提供のプロパティ ハンドラーを登録できます。

形式 CLSID
OLE DocFile {8d80504a-0826-40c5-97e1-ebc68f953792}
セーブ ゲーム XML {ECDD6472-2B9B-4b4b-AE36-F316DF3C8D60}
XPS/OPC ハンドラー {45670FA8-ED97-4F44-BC93-305082590BFB}
XML {c73f6f30-97a0-4ad1-a08f-540d4e9bc7b9}

 

カスタム プロパティを作成する前に、代わりに使用できるシステム定義プロパティがないことを確認する必要があります。 システム定義のプロパティを列挙するには、PSEnumeratePropertyDescriptions を呼び出すか、prop.exe コマンド ライン ツールを使用します。

システム スキーマでは、これらのプロパティがインデクサーと対話する方法が定義されており、これを変更することはできません。 さらに、ファイルの種類を作成、編集、保存するために使用するアプリケーションも、特定の動作に準拠している必要があります。 たとえば、アプリケーションが安全な保存 (編集中に一時ファイルが作成され、ReplaceFile() を使用して新しいバージョンと古いバージョンを入れ替える) を実装している場合、元のファイルから新しいファイルにすべてのプロパティを転送する必要があります。 これに失敗すると、ユーザーまたは他のアプリケーションによって追加されたプロパティがファイルで失われることになります。

 

以下に、.OLEDocFile 拡張子を持つファイルの種類に対するシステム提供の OLE DocFile ハンドラーの登録を示します。

HKEY_CLASSES_ROOT
   SystemFileAssociations
      .OLEDocFile
         shellex
            {BB2E617C-0920-11d1-9A0B-00C04FC2D6C1}
               (Default) = {9DBD2C50-62AD-11d0-B806-00C04FD706EC}

以下は、OLEDocFile ファイルのプロパティが、[詳細] タブおよびペインに表示されるようにするための、プロパティ リスト情報の登録を示しています。

HKEY_CLASSES_ROOT
   SystemFileAssociations
      .OLEDocFile
         ExtendedTileInfo = prop:System.ItemType;System.Size;System.DateModified;System.Author;System.OfflineAvailability
         FullDetails = prop:System.PropGroup.Description;System.Title;System.Subject;
System.Keywords;System.Category;System.Comment;System.PropGroup.Origin;
System.Author;System.Document.LastAuthor;System.Document.RevisionNumber;
System.Document.Version;System.ApplicationName;System.Company;System.Document.Manager;
System.Document.DateCreated;System.Document.DateSaved;System.Document.DatePrinted;
System.Document.TotalEditingTime;System.PropGroup.Content;System.ContentStatus;
System.ContentType;System.Document.PageCount;System.Document.WordCount;
System.Document.CharacterCount;System.Document.LineCount;
System.Document.ParagraphCount;System.Document.Template;System.Document.Scale;
System.Document.LinksDirty;System.Language;System.PropGroup.FileSystem;
System.ItemNameDisplay;System.ItemType;System.ItemFolderPathDisplay;
System.DateCreated;System.DateModified;System.Size;System.FileAttributes;
System.OfflineAvailability;System.OfflineStatus;System.SharedWith;
System.FileOwner;System.ComputerName
         InfoTip = prop:System.ItemType;System.Size;System.DateModified;System.Document.PageCoun
         PerceivedType = document
         PreviewDetails = prop:*System.DateModified;System.Author;System.Keywords;
*System.Size;System.Title;System.Comment;System.Category;
*System.Document.PageCount;System.ContentStatus;System.ContentType;
*System.OfflineAvailability;*System.OfflineStatus;System.Subject;
*System.DateCreated;*System.SharedWith

 

リファレンス

プロパティ マッピング

Conceptual

Windows Search でフィルター ハンドラーを作成するためのベスト プラクティス

インデックス作成プロセス

プロトコル ハンドラーの開発

カスタム ファイル形式のシステム定義プロパティ

その他のリソース

プロパティ システム

システム プロパティ

Windows Search のコード サンプル