次の方法で共有


Shell Instance オブジェクトによるシェル拡張の作成

Raymond Chen
Microsoft Corporation

February 2000

要約 : 従来のシェル名前空間拡張は、COM インプロセス サーバーの実装を必要としました。Shell Instance オブジェクトを使用すると、コーディングはまったく必要なく、簡易シェル拡張を作成することができます。この記事は、Shell Instance オブジェクトと Shell Command オブジェクトを使って、簡易シェル拡張を簡単におこなう方法を記述したものです。

内容

シェル名前空間拡張とは
Shell Instance オブジェクトとは
Shell Instance オブジェクトとして作成できる Shell オブジェクト
サンプル
Shell Commandオブジェクト
結論

シェル名前空間拡張とは

シェル名前空間拡張を使用すると、シェル内に "仮想フォルダ" を作成することができます。たとえば、デスクトップ上の [ごみ箱] アイコンは、本当のファイル システム ディレクトリではありません。ごみ箱シェル拡張により保管されているアイテムのコレクションを表します。

シェル名前空間拡張の詳細については、MSDN ライブラリのプラットフォーム SDK (https://msdn.microsoft.com/library/bb776812.aspx.) を参照してください。

シェル名前空間拡張の記述は非常に面倒です。しかし、ここでも説明するように、特定の種類の簡易シェル名前空間拡張については、簡単に作成する方法がシェルから提供されています。

Shell Instance オブジェクトとは

" Shell Instance オブジェクト " は、shdocvw.dll コンポーネントにより提供される特殊なシェル拡張です。従来のシェル拡張は、オブジェクトの実装に DLL を必要としますが、Shell Instance オブジェクトは、レジストリから必要なすべての情報を取得しています。

Shell Instance オブジェクトが生成されるプロセス

  1. shdocvw.dll コンポーネントが、Shell Instance オブジェクトの InProcServer32 として登録されることによりロードされます。

  2. shdocvw.dll は、レジストリからでないと認識できないオブジェクトを作成するように指示されると、Instance というサブキーでレジストリ キーをチェックします。このサブ キーが見つかれば、その CLSID 値を読み込み、その CLSID を CoCreateInstance 関数に渡します。あまり適切とは言えませんが、これを "ホスト" オブジェクトと呼びます。

  3. 次に、shdocvw.dll は、Instance のサブキー、InitPropertyBag または InitStream を検索します。見つかれば、レジストリ キーの内容に従って、それぞれ IPropertyBag または IStream を作成し、これを IPersistPropertyBag::Load メソッドまたは IPersistStream::Load メソッドに渡します。

  4. 最後に、shdocvw.dll は、初期化されたホスト オブジェクトを Shell Instance オブジェクトとして戻します。

Shell Instance オブジェクトとして作成できる Shell オブジェクト

Shell Instance オブジェクトのホスト オブジェクトになれる 2 つの Shell オブジェクトは、" Shell link オブジェクト " と " Shell folder shortcut オブジェクト " の 2 つの Shell オブジェクトです。

これらのオブジェクトは両方とも、 InitPropertyBag インターフェイスをサポートしているので、これらを初期化する InitPropertyBag メソッドを使用することができます。これらのオブジェクトは IPersistStream もサポートしていますが、レジストリ ストリームからショートカットを初期化するのは非常に面倒です。

レジストリ内のプロパティ バッグは、シェル リンク オブジェクトまたはシェル フォルダ ショートカット オブジェクトのターゲットを示します。このプロパティ バッグには次の 3 つの種類があります。

シェル特殊フォルダをターゲットとする


InitPropertyBag
    TargetSpecialFolder=REG_SZ:"<特殊フォルダ番号>"

これは、整数を表していても、REG_SZ レジストリ値になることに注意してください。10 進表記法と 16 数表記法の両方がサポートされています。

シェル特殊フォルダ内のディレクトリをターゲットとする


InitPropertyBag
    TargetSpecialFolder=REG_SZ:"<特殊フォルダ番号>"
    Target=REG_SZ:"<サブディレクトリ名>"

サブディレクトリ名には、埋め込み円記号 (\) を含めることができます。

明示パスでディレクトリをターゲットにする


InitPropertyBag
    Target=REG_SZ:"<ターゲット ディレクトリへのフル パス>"

サンプル

次のサンプルは、コントロール パネルの [フォント] フォルダを作成するレジストレーションのコピーです。


HKEY_CLASSES_ROOT

CLSID
   {D20EA4E1-3957-11D2-A40B-0C5020524152}=REG_SZ:"Fonts"
      InfoTip=REG_SZ:"Displays and manages fonts on your computer"
      DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\system32\main.cpl,9"
      InProcServer32=REG_EXPAND_SZ:"%SystemRoot%\system32\shdocvw.dll"
        ThreadingModel=REG_SZ:"Apartment"
      ShellFolder
        Attributes=REG_DWORD:0x60000000
        WantsFORPARSING=REG_SZ:""
      Instance
        CLSID=REG_SZ:"{0AFACED1-E828-11D1-9187-B532F1E9575D}"
        InitPropertyBag
          TargetSpecialFolder=REG_SZ:"0x0024"
          Target=REG_SZ:"Fonts"

コントロール パネル名前空間に {D20EA4E1-3957-11D2-A40B-0C5020524152} が登録されるので、[フォント] フォルダ ショートカットがコントロール パネルにインストールされます。

このレジストリ キーを、順を追って見ていきましょう。

  • Platform SDK で検索された uuidgen プログラムを実行することにより、GUID {D20EA4E1-3957-11D2-A40B-0C5020524152} が生成されました。独自のインスタンス オブジェクトを作成する際には、uuidgen を実行し、独自の GUID を使用することが必要です。名前空間内に現れるアイコン名もここで提供されます。

  • マウス ポインタをアイコン上で動かすと、オプションの InfoTip 文字列が表示されます。

  • DefaultIcon 文字列は、このアイテムに対して表示するアイコンの名前とアイコン インデックスを提供します。

  • InProcServer32 キーが shdocvw.dll ファイルに設定され、スレッド モデルがアパートメントに設定されている必要があります。

  • ShellFolder キーにより、属性が SFGAO_ 値のコレクションに設定されます。これはフォルダ ショートカットに使用されます。SFGAO_FOLDER フラグが必要です。ターゲットがファイル システム フォルダなので、SFGAO_FILESYSTEM フラグも属性に設定され、WantsFORPARSING 値が空白文字列に設定されます (ターゲットがファイル システム フォルダでなければ、WantsFORPARSING 値は必要ありません)。

  • Instance キーにより、CLSID 値が CLSID_FolderShortcut の文字列に設定されます。これは、このオブジェクト インスタンスがフォルダ ショートカットを作成しなければならないことを示します。

  • InitPropertyBag キーでは、IPersistPropertyBag インターフェイスによりフォルダ ショートカットが初期化されることを示します。プロパティ バッグ内の 2 つの値により、ターゲットが、CSIDL_WINDOWS である特殊フォルダ 0x0024 内のサブディレクトリ "Fonts" であることが指定されます。

Shell Commandオブジェクト

シェル拡張オブジェクトのもう一つのタイプは、ダブルクリックによりコマンドを実行するアイコンです。これも、COM サーバーを記述する必要なく作成することができます。次は、マイ ネットワーク フォルダにより使用されるコマンド オブジェクトです。


HKEY_CLASSES_ROOT

CLSID
  {D4480A50-BA28-11d1-8E75-00C04FA31A86}=REG_SZ:"Add Network Place"
       InfoTip=REG_SZ:"Connects to shared folders, Web folders, and FTP sites."
       DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\System32\netplwiz.dll,-107"
        ShellFolder
        Attributes=REG_DWORD:0x00000000
    Shell
Open
   Command=REG_EXPAND_SZ:"rundll32 ..."

このレジストリ キーはあまり珍しいものではないので、Shell Instance オブジェクトとの違いについてのみ説明します。

  • InProcServer32 キーはありません。

  • これはフォルダではないので、 ShellFolder キーの属性に SFGAO_FOLDER フラグは含まれません。

  • ここでは、 Instance キーではなく、 Shell キーを使用します。これは、progid キーと同じ構造になっています。ダブルクリックのアクションは、[開く] が既定値になります。ショートカット メニューに表示されるそのほかの動詞を作成することもできます。たとえば、[Internet Explorer] アイコンでは、[ホーム ページを開く] というカスタム アクションが使用されています。

Shell キーの構造の詳細については、MSDN ライブラリのプラットフォーム SDK にある「Extending Context Menus」(" https://msdn.microsoft.com/library/bb776820.aspx") を参照してください。

結論

Shell Instance オブジェクトと Shell Commandオブジェクトを使用すると、簡易シェル拡張を簡単におこなうことができます。たとえば、[コントロール パネル] フォルダ内に、"Troubleshoot" というコマンド オブジェクトを作成し、ここから、トラブルシューティング プログラムを起動させることができます。また、共有ネットワーク サーバー上のシステム管理ツールのコレクションに、フォルダ ショートカットとなる Shell Instance オブジェクトを作成することができます。Shell Instance オブジェクトと Shell Command オブジェクトにより、このタイプのシェル拡張を簡単におこなうことができます。