search
LoginSignup
3

More than 3 years have passed since last update.

posted at

updated at

Windows Installer手引書 Part.5 ファイル拡張子の関連付け

前の記事へ  目次へ  次の記事へ

ファイル拡張子の関連付け

インストーラーで最もよく使われるレジストリは、ファイル拡張子の関連付けではないかと思います。

基本

プログラムをインストールする際、そのプログラムのデータファイルをダブルクリックしたときにプログラムを起動してデータを読ませるよう設定する、という要求はよくあります。関連付けはレジストリに書き込みます。例えば、プログラムyourapp.exeが拡張子.papaというデータファイルを使用するなら、次のようになります。

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = YourProgID
 + YourProgID
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\yourapp.exe" "%1"

ここで、YourProgID[Vendor or Application].[Component].[Version]といった形式が推奨されています。全体的な情報は、Application RegistrationFile Typesあたりから読み進めていけば一通り得られます。例えばWiXでは、下記のようなソースで表現できます。このコードで、プログラムprTxtAのデータファイルとして、拡張子.papaのファイルを関連付けます。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="956fe4e0-24eb-4e2f-89c4-18fd051f216e">
 4:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 5:   <RegistryValue Id="extRegv" Root="HKCR" Key=".papa" Type="string" Value="$(var.prgid)" />
 6:   <RegistryValue Id="comRegv" Root="HKCR" Key="$(var.prgid)\shell\open\command" Type="string" Value="&quot;[#prTxExeFile]&quot; &quot;%1&quot;" />
 7:              :
 8:              :
 9: </Component>

基本はこれで良いのですが、ちょっとした落とし穴があります。

他のアプリと利用する拡張子がかぶる

よく使われるメジャーなデータ形式は色々なアプリが拡張子の関連付けを奪い合います。また、同じアプリの異なるバージョンを一つのPCで利用できるケースもあり、どのように拡張子の関連付けを管理していくか悩むところです。先の基本で例示したレジストリ構造を見れば分かるように、何も考えずにすでに関連付け済みの拡張子に関連付けをすると、古い関連付けの情報は消えてしまいます。そこでまず、この部分

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = YourProgID

アンインストール時に削除しないことが推奨されています

さらにWindowsには、ファイルアイコンを右クリックするとメニューに現れる「プログラムから開く」や、「ファイルの種類ごとに既定のアプリを選ぶ」機能があります。ここにインストールしたアプリを一覧表示させることで、容易にユーザーが拡張子の関連付けを変更できるようになります。下記のように、拡張子のキーの下にOpenWithProgidsキーを置くことで実現します。これは、prTxtAとprTxtBの2つのアプリをインストールした後の状態を示します。

HKEY_CLASSES_ROOT
 + .papa
 |  + (Default) = prTxtB.extcmd.1
 |  + OpenWithProgids
 |     + prTxtA.extcmd.1 = ""
 |     + prTxtB.extcmd.1 = ""
 + prTxtA.extcmd.1
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\prTxtA.exe" "%1"
 + prTxtB.extcmd.1
 |  + shell
 |     + open
 |        + command
 |           + (Default) = "fullpath\prTxtB.exe" "%1"

こうすると一覧から自分のアプリを容易に選べるようになります。
Part5Fig01.png

削除されないレジストリ(やファイル)をインストールする最も簡単な方法はComponentにPermanent属性を付けることでしょう。下記のソースのように削除しないレジストリを別のComponentに切り出せば実現できます。アンインストールすると実体のないProgIDが残ることになりますが、ProgIDが登録されていない場合は無視されるので問題ありません。ただし気を付けなければいけないのは、ComponentにPermanent属性を付けると、アンインストールしても環境にComponentの登録情報が残ることです。インストーラーのテストの都合でComponentの登録情報を削除する場合は、手動でレジストリから情報を消す必要があります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id ="extCompo" Permanent="yes" Guid="bcadce47-ae51-4ad1-9391-227c998dea85">
 4:   <RegistryValue Id="extReg"      Root="HKCR" Key=".papa"                           Type="string" Value="$(var.prgid)" KeyPath="yes" />
 5: </Component>
 6: <Component Id="prgCompo" Guid="a5c70bd9-9158-4c0c-b8f4-4376bbc6e1fb">
 7:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 8:   <RegistryValue Id="openwithReg" Root="HKCR" Key=".papa\OpenWithProgids"           Type="string" Name="$(var.prgid)" Value="" />
 9:   <RegistryValue Id="comRegv"     Root="HKCR" Key="$(var.prgid)\shell\open\command" Type="string" Value="&quot;[#prTxExeFile]&quot; &quot;%1&quot;" />
10:              :
11:              :
12: </Component>

アイコン画像をデータファイルに割り当てる

MSDN Libraryの情報では、Programmatic Identifiersが参考になります。

  • アイコンファイルに割り当てる場合

progIDのキーの下にDefaultIconキーを置き、下記のようにアイコンファイルへのパスを記述します。

HKEY_CLASSES_ROOT
 + YourProgID
 |  + DefaultIcon
 |     + (Default) = fullpath\blueData.ico

WiXのソースは、例えば下記のようになります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="a5c70bd9-9158-4c0c-b8f4-4376bbc6e1fb">
 4:              :
 5:              :
 6:   <File Id="iconFile" Source="blueData.ico" />
 7:   <RegistryValue Id="iconReg" Root="HKCR" Key="$(var.prgid)\DefaultIcon" Type="string" Value="&quot;[$prgCompo]\blueData.ico&quot;" />
 8: </Component>
  • EXE,DLLのリソース中にあるアイコン画像を使う場合

ファイル名の後に何番目(0が1番目)のアイコンか指定します。例えば、リソースの2番目のアイコン画像を使うなら、次のようになります(DLLの場合も同じ書式です)。

HKEY_CLASSES_ROOT
 + YourProgID
 |  + DefaultIcon
 |     + (Default) = fullpath\prTxtA.exe,1

WiXのソースは、例えば下記のようになります。

 1: <?define prgid="prTxtA.extcmd.1"?>
 2: 
 3: <Component Id="prgCompo" Guid="387e3686-06e3-4cdf-9992-9c8ea7da56bc">
 4:              :
 5:              :
 6:   <File Id="prTxExeFile" KeyPath="yes" Source="..\prTxtA_SRC\prTxtA.exe" />
 7:   <RegistryValue Id="iconReg" Root="HKCR" Key="$(var.prgid)\DefaultIcon" Type="string" Value="[$prgCompo]\prTxtA.exe,1" />
 8: </Component>

[#prTxExeFile]や[$prgCompo]などの表現の意味

これまで何の説明もなくWiXのソースに使ってきましたが、これらはMSIの機能です。[#prTxExeFile]は、prTxExeFileというIdで定義したファイルへのフルパスを示します。[$prgCompo]は、prgCompoというIdで定義したコンポーネントのフォルダ・パスを示します。これらはインストールの実行時に値が入れられるのでパスをハード・コーディングするよりは良い方法です。

パスを表現する方法

環境変数を使ってパスを指し示す方法もあります。

前の記事へ  目次へ  次の記事へ

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3