(この記事はブログを始める前に書いた記事を書き写したものです)
Created: 2005年2月19日
Last modified: 2007年5月9日
概要
念願のThinkPad (Windows XP搭載)購入を受けまして、Windows XPで新しくなった関連づけシステムについて調べてわかった事を書いていきます。
背景
Windows XPにした途端に関連づけがうまく働かなくなった、という話をいろいろな日記や掲示板などで見かけます。具体的には「画像ファイルの関連づけ設定を変更しても『Windows画像とFAXビューア』が起動してしまって困っている」といったものです。私も、叔父のPCを設定する時に困った覚えがあります。
改めて関連づけの仕組みについて調べたところ、MSDNの開発者向け文書に詳しいものを見つけました。Creating a File Associationという文書です。これを読むと、現在の仕様がかなり複雑になっている事が分かります。互換性のために残っている過去の仕様が主な原因ではありますが、それらを理解せずに理解できるような仕様でもないため、理解するのが少し大変な状態になっています。
関連付け設定方法の概説
まず関連付けに使われる設定方法で一番知られているのは「ファイルクラス」を定義する方法です。具体的にはHKEY_CLASSES_ROOT下にある”.”付きの拡張子と同名のキーを使うものです。HKEY_CLASSES_ROOTはHKEY_LOCAL_MACHINE\Software\Classesの別名ですから、これはシステム全体に対する設定になっています。システム全体に対する関連付け設定は全ユーザに共通した設定になるのですから、ユーザ個別の関連付け設定をこの方法で行う事はできません。恐らくこれはマルチアカウントの意識がなかったWindows 9x時代からの仕組みなのでしょう。
ユーザ個別の関連付け設定を可能にするために導入されたと思われるのがUser Customized Keyと呼ばれる設定方法です。この方法では名前の通り、ユーザごとに関連づけを自由に定義できます。なお、これはユーザ個別の設定ですから管理者権限のないユーザでも設定を変更可能である必要があります。そのため必然的にHKEY_CURRENT_USER下にあるキーで行うようになっています。
仕様の概要
Windows XPにおける関連づけ設定に使うキーを優先される順に並べると次のような表になります。ただしここではWindows XP標準状態での.bmpファイルを例にしています。
MSDNでの呼び方 | 該当キー | 用途 |
---|---|---|
User Customized Key | HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.bmp | ユーザーごとの関連づけ設定 |
ProgID Key | HKEY_CLASSES_ROOT\Paint.Picture | アプリケーションのバージョン管理機能(もどき)付き関連づけ指定 |
System File Association Key | HKEY_CLASSES_ROOT\SystemFileAssociations.bmp | 全ユーザー共通の関連づけ設定 |
System File AssociationPerceived Type Key | HKEY_CLASSES_ROOT\SystemFileAssociations\image | 同類ファイルタイプに共通の関連づけ設定 |
Basic Class Key | HKEY_CLASSES_ROOT\* | 全ファイルタイプに共通の関連づけ設定 |
All File System Objects Key | HKEY_CLASSES_ROOT\fileやHKEY_CLASSES_ROOT\folderやHKEY_CLASSES_ROOT\directory | すべてのファイル、フォルダ、ディレクトリの関連づけ設定 (そもそも拡張子を区別せず) |
基本的にWindowsの関連づけシステムでは拡張子を最重要視します。これはOSが拡張子以外でファイルタイプを識別できないために当然の事ですね。上に挙げたどのキーでも、まずは拡張子と同名のキーを使います(下二つをのぞく)。
ProgID Key
まず、一般的に最もよく知られていると思われる関連づけ設定のキーはProgID Keyだと思います。これは元々の関連づけ設定方法を開発者用の約束事で拡張した方法です。Windowsはこのキーを使った場合、次のように関連づけ情報を取得します(先ほどに引き続き.bmpを例にします)。
- HKEY_CLASSES_ROOT.bmpの標準値を取得(”Paint.picture”だったとする)
- HKEY_CLASSES_ROOT\Paint.pictureのサブキーCurVerの標準値を取得(”Paint.picture.1″だったとする)
- HKEY_CLASSES_ROOT\Paint.picture.1キーを取得、そこから関連づけ情報を取得
実はこの通りに設定しているアプリケーションは少なく、MicrosoftのWord 97でもこの通りには設定していませんね。よく使われているのは(あるいは古い方法)次のように設定する方法です。
- HKEY_CLASSES_ROOT.bmpの標準値を取得(”bmpfile”だったとする)
- HKEY_CLASSES_ROOT\bmpfileキーを取得、そこから関連づけ情報を取得
さて、どちらの方法でも基本的には最後にたどり着いたキー(前者ではPaint.picture.1、後者ではbmpfileキー)が関連づけを設定します。その仕組みを紹介します。
まず、このキーの標準値は、マイコンピュータやエクスプローラで「ファイルの種類」として表示される文字列になります。このキーのサブキー「DefaultIcon」の標準値は、そのファイルのアイコンのパス(とインデックス)を指定します。このキーのサブキー「shell」は、そのファイルタイプの関連づけ(アクション)を設定します。アクションは、「shell」キーの下にそのアクション用のサブキー(名前は自由)を作り、そのサブキー「Command」の標準値でそのアクションを定義します。なおアクションはいくつでも定義できます。その場合は「shell」キーの下に複数のアクション用のサブキーを作ります。では最後に例を一覧表にまとめておきます。
キーの例 | 値の名前 | 値の例 | 意味・用途 |
---|---|---|---|
HKEY_CLASSES_ROOT\bmpfile | (標準) | ビットマップ・イメージ | 「ファイルの種類」で表示される文字列 |
HKEY_CLASSES_ROOT\bmpfile\DefaultIcon | (標準) | C:\WINDOWS\system32\shimgvw.dll,2 | 「ファイルの種類」で表示される文字列 |
HKEY_CLASSES_ROOT\bmpfile\shell | (標準) | open | 標準(ダブルクリック)のアクションをサブキー名で指定 |
HKEY_CLASSES_ROOT\bmpfile\shell\open | (標準) | 開く(&O) | 右クリック時に表示されるこのアクションの名前 |
HKEY_CLASSES_ROOT\bmpfile\shell\open | MUIVerb | @shimgvw.dll,-550 | (後述) |
HKEY_CLASSES_ROOT\bmpfile\shell\open\command | (標準) | rundll32.exe C:\WINDOWS\System32\shimgvw.dll %1 | コマンドラインによるアクションの定義 |
HKEY_CLASSES_ROOT\bmpfile\shell\open\ddeexec | (標準) | Open(“%1”) | DDE によるアクションの定義 |
HKEY_CLASSES_ROOT\bmpfile\shell\open\ddeexec | application | msdev | DDE を行うアプリケーションの指定 |
HKEY_CLASSES_ROOT\bmpfile\shell\open\DropTarget | Clsid | {E84FDA7C-1D6A-45F6-B725-CB260C236066} | 指定 CLSID の COM コンポーネントの IDropTarget インターフェイスを使うアクションの定義 |
HKEY_CLASSES_ROOT\bmpfile\shell\xnview | (標準) | XnView で開く(&X) | 右クリック時に表示されるこのアクションの名前 |
HKEY_CLASSES_ROOT\bmpfile\shell\xnview\command | (標準) | “C:\Program Files\XnView\XnView.exe” “%1” | アクションの定義 |
HKEY_CLASSES_ROOT\bmpfile\shell\bmp2png | (標準) | PNG に変換(&P) | 右クリック時に表示されるこのアクションの名前 |
HKEY_CLASSES_ROOT\bmpfile\shell\bmp2png\command | (標準) | “C:\Program Files\bin\bmp2png.exe” “%1” | アクションの定義 |
なお、DDE (Dynamic Data Exchange)について私はまったく知りません(興味がない)。ただ、注意しないといけないのはアクション定義の優先順位です。アクションを表すキーのサブキーにはcommand、ddeexec、DropTargetがあり、これらはそれぞれ違う方法でアクションを定義しています。この中で最優先されるのはDropTargetです。従ってこのキーが存在しているファイルタイプのcommandキーをいくら更新しても関連づけは変わりません。
これについて何を注意しなければならないのかというと、まず仕様としてファイルタイプのキーで標準のアクションを指定しない場合、openという名前のキーで定義されたアクションが標準になります。従って、アプリケーションの「あるファイルタイプに関連づけする」という処理はだいたいこのopenキーを書き換えています。しかし、このDropTargetはWindows XPで初めて搭載された機能ですのでXP以前に作られたアプリケーションではこのキーを書き換えません。するとアプリケーション側からすると正常に関連づけ設定ができているのに実際にはDropTargetの設定が優先されて関連づけができていない状態になってしまいます。これがよく聞かれる「関連づけが更新されない」問題の原因です。
なお、この場合アイコンの変更は反映されます。また、右クリックの時に出てくる文字列も変更されると思うのですが、後述のMUIVerbという仕組みがあるため、その文字列も更新されません。つまりアイコンと「ファイルの種類」が変更されるのに起動するアプリケーションが変化しない、という状況になってしまうわけですね。厄介です。
User Customized Key
前述の通り、ユーザーごとに独立した設定を行う事ができる上に最も優先される設定です。HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExtsキーのサブキー群で設定が行われます。このキーのサブキーに拡張子と同名のキーを作成し、そのキーに”Application”という名前の文字列値を作成します。この文字列値の値がこのファイルタイプのファイルを開く標準アプリケーションになります。これにはシステムに登録されているアプリケーション(後述)の実行ファイル名、あるいは実行ファイルのパスで指定できます。
少々話がそれますが、システムに登録されているアプリケーションというのはファイルの右クリックメニューの項目「プログラムから開く」から「プログラムの選択」で出てくる一覧画面で現れるものです。これは次のレジストリキーに登録されています(登録方法は割愛)。
HKEY_CLASSES_ROOT\Applications
どうもこの仕様が作られた頃はMicrosoftの方針が昔のものと違うように感じられます。従来通りの関連づけではアプリケーションもアイコンもパスで指定するため、アプリケーションの場所を変更してしまうとそのアプリケーションに関連づけられていたすべてのファイルの関連づけがおかしくなります。そこで、関連づけという概念を従来の「拡張子とアプリケーション、アイコン」という関係から「ファイルタイプとそれを開くアプリケーション」の関係にしようとしているように思われます。後者のメリットは、アプリケーション自身が自分自身の場所を申告する事でアプリケーションのパスが変わってもすぐに全ファイルの関連づけが更新できる事でしょう。デメリットは、アイコンなどの設定が独立していないためアプリケーション側の指定したもの、ファイルアイコンを自由に変更できません(このあたりは中途半端ですね)。Macintoshの思想に影響を受けているのだと思いますが、個人的にはその思想がどんなにすばらしいものだとしても、複数の思想が入り乱れるぐらいなら導入しない方が無難だったと思いますね(苦笑)。
SystemFileAssociations Key
この種類の関連づけ方法は正直に言って何のためにあるのか私にはわかりません。ProgIDキーと何が違うのかと思ってしまいます(苦笑)。ただ、違う事があるとすれば拡張子と同名のキーに直接関連づけ情報を書き込む事でしょうか。あまりこの設定を使う事はないと思います。
SystemFileAssociations PerceivedType Key
PerceivedTypeを用いて関連付けを設定すると、個々の具体的なファイルタイプではなくファイルタイプの「分類」に対して関連付けを行う事ができます。例えば各種の画像ファイルタイプに同じ画像ビュワーに関連づけたいなど、同じ分類のファイルタイプに一括して関連づけ設定をしたい場合に役立ちます。
PerceivedTypeとは、先の話で言うところのファイルタイプの「分類」と同じものです。例として.bmp、.pngを考えましょう。これらはみな画像ファイルの形式で、それもベクトル画像ではなくラスタ画像です。Windows XPではラスタ画像という分類にあたるPerceivedTypeとしてimageというタイプが用意されています。
具体例として.bmpなどのラスタ画像のファイルタイプにimageというPerceivedTypeを設定する方法を述べます。まずHKEY_CLASSES_ROOT下の.bmpと.pngというキーにPerceivedTypeという文字列値を定義し、その値をimageにします。次にHKEY_CLASSES_ROOT\SystemFileAssociationsキーの下にimageという名前のキーを作ります。このキーでProgIDキーと同様の関連づけ情報を定義すると、同じPerceivedTypeが指定された全ファイルタイプに対し、一括してアクションおよびアイコンが適用されます。なお、前述の優先順位によってPerceivedTypeの設定が上書きされる事がありますので注意してください。
なお、Windows XPがあらかじめ定義しているPerceivedTypeは次の6つです。
- Image
- Text
- Audio
- Video
- Compressed
- System
残念ながらWindows XPでは独自にPerceivedTypeを定義する方法は無いようです。したがって、この仕組みでは定義済みタイプに入らない種類のファイルに関連付けを行う事はできない、と考えた方が良いでしょう。
MUIVerbキー
最後にMUIVerbキーについて説明します。まずMUIはMultilingual User Interfaceの略でして、多言語対応の一環としてWindowsが複数の言語にローカライズされた複数のユーザーインターフェイスを用意する、というコンセプト(?)があります。要するにMUIという思想の影響がありそうなverb(動詞)という感じです(まあ名前はどうでもいいですしね(苦笑))。実際にこれが何の役割を果たすかというと、言語環境に応じてアクションの表示名を自動的に切り替える機能を果たします。
まず「各ファイルタイプのキー(ProgID\bmpfile、SystemFileAssociations\bmpfileなど)のサブキーshellの下にある、そのファイルに対するアクションを定義するレジストリキー」ですが、一般的にはその標準値に右クリックメニューでの項目名を指定する事になります。しかしこれではレジストリ上に表示名を直接打ち込む事になるため、アプリケーション作者が言語環境に応じて表示名を切り替えるのが難しくなります。そこで言語環境に応じて表示名を切り替える仕組みが求められてきます。
MUIVerbによるアクションの表示名指定は次のような手順で行います。アクションの定義キーに”MUIVerb”という文字列値を作り、そこに「表示させたい項目名の格納されたファイルのパス」と、「そのファイル内に格納されたその項目名の文字列リソース番号」を指定します。なお、一般的なファイル参照と違うためかこの項目の値は先頭に”@”をつけます。具体的な例をあげると次のようになります。
@C:\WINDOWS\System32\shimgvw.dll,-550
ここからはWindowsアプリケーション開発者でないと分からないかもしれませんが、多くのWindowsアプリケーションは内部に「リソース」という形でアイコンや文字列などを持っていますので、MUIVerbにそれを指定して用います。この方法には何のメリットがあるのかと言うと、アプリケーション内のリソースには言語環境に応じて内容を自動的に切り替える機能があります。つまり日本語環境では日本語の文字列リソースを、英語環境では英語の文字列リソースを表示させる事ができるようになっているわけです。MUIVerbを利用する場合、アプリケーションに文字列の管理を任せる事になるのでこの環境に応じた自動切り替え機能が使えます。しかし逆を言うとアプリケーションの開発環境と開発技術が必要になるので個人的には「かなりどうかと」思う機能ではあります。
ただ、一つ気をつけなくてはならない事があります。このMUIVerbキーの設定がある場合、アクションを表すキーの標準値に何がセットされていようとMUIVerbの方が優先されます。従ってMUIVerbを使って表示名が設定されているアクションは単純に標準値を書き換えるだけでは変更が反映されません。
終わりに
調べている最中に分かってきた事が多く、非常に疲れました(苦笑)。私がこの記事を書く事で得たものは、PerceivedTypeの有用性とDropTargetという騒動の犯人です。まあ本当は後者のためだったはずですが・・・この疲れ方は「釣り合ってない」なぁと今更ながら思ってみたりします(苦笑)。
謝辞
やすひささんよりいただいたフィードバックにより、この記事の内容を改善できました。ありがとうございます。