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 オブジェクトが生成されるプロセス
shdocvw.dll コンポーネントが、Shell Instance オブジェクトの InProcServer32 として登録されることによりロードされます。
shdocvw.dll は、レジストリからでないと認識できないオブジェクトを作成するように指示されると、Instance というサブキーでレジストリ キーをチェックします。このサブ キーが見つかれば、その CLSID 値を読み込み、その CLSID を CoCreateInstance 関数に渡します。あまり適切とは言えませんが、これを "ホスト" オブジェクトと呼びます。
次に、shdocvw.dll は、Instance のサブキー、InitPropertyBag または InitStream を検索します。見つかれば、レジストリ キーの内容に従って、それぞれ IPropertyBag または IStream を作成し、これを IPersistPropertyBag::Load メソッドまたは IPersistStream::Load メソッドに渡します。
最後に、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 オブジェクトにより、このタイプのシェル拡張を簡単におこなうことができます。